mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 21:12:24 -05:00 
			
		
		
		
	
		
			
	
	
		
			102 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			102 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | /* | ||
|  |  * | ||
|  |  * Copyright 2019 gRPC authors. | ||
|  |  * | ||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||
|  |  * you may not use this file except in compliance with the License. | ||
|  |  * You may obtain a copy of the License at | ||
|  |  * | ||
|  |  *     http://www.apache.org/licenses/LICENSE-2.0 | ||
|  |  * | ||
|  |  * Unless required by applicable law or agreed to in writing, software | ||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  |  * See the License for the specific language governing permissions and | ||
|  |  * limitations under the License. | ||
|  |  * | ||
|  |  */ | ||
|  | 
 | ||
|  | // Package attributes defines a generic key/value store used in various gRPC | ||
|  | // components. | ||
|  | // | ||
|  | // # Experimental | ||
|  | // | ||
|  | // Notice: This package is EXPERIMENTAL and may be changed or removed in a | ||
|  | // later release. | ||
|  | package attributes | ||
|  | 
 | ||
|  | // Attributes is an immutable struct for storing and retrieving generic | ||
|  | // key/value pairs.  Keys must be hashable, and users should define their own | ||
|  | // types for keys.  Values should not be modified after they are added to an | ||
|  | // Attributes or if they were received from one.  If values implement 'Equal(o | ||
|  | // interface{}) bool', it will be called by (*Attributes).Equal to determine | ||
|  | // whether two values with the same key should be considered equal. | ||
|  | type Attributes struct { | ||
|  | 	m map[interface{}]interface{} | ||
|  | } | ||
|  | 
 | ||
|  | // New returns a new Attributes containing the key/value pair. | ||
|  | func New(key, value interface{}) *Attributes { | ||
|  | 	return &Attributes{m: map[interface{}]interface{}{key: value}} | ||
|  | } | ||
|  | 
 | ||
|  | // WithValue returns a new Attributes containing the previous keys and values | ||
|  | // and the new key/value pair.  If the same key appears multiple times, the | ||
|  | // last value overwrites all previous values for that key.  To remove an | ||
|  | // existing key, use a nil value.  value should not be modified later. | ||
|  | func (a *Attributes) WithValue(key, value interface{}) *Attributes { | ||
|  | 	if a == nil { | ||
|  | 		return New(key, value) | ||
|  | 	} | ||
|  | 	n := &Attributes{m: make(map[interface{}]interface{}, len(a.m)+1)} | ||
|  | 	for k, v := range a.m { | ||
|  | 		n.m[k] = v | ||
|  | 	} | ||
|  | 	n.m[key] = value | ||
|  | 	return n | ||
|  | } | ||
|  | 
 | ||
|  | // Value returns the value associated with these attributes for key, or nil if | ||
|  | // no value is associated with key.  The returned value should not be modified. | ||
|  | func (a *Attributes) Value(key interface{}) interface{} { | ||
|  | 	if a == nil { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 	return a.m[key] | ||
|  | } | ||
|  | 
 | ||
|  | // Equal returns whether a and o are equivalent.  If 'Equal(o interface{}) | ||
|  | // bool' is implemented for a value in the attributes, it is called to | ||
|  | // determine if the value matches the one stored in the other attributes.  If | ||
|  | // Equal is not implemented, standard equality is used to determine if the two | ||
|  | // values are equal. Note that some types (e.g. maps) aren't comparable by | ||
|  | // default, so they must be wrapped in a struct, or in an alias type, with Equal | ||
|  | // defined. | ||
|  | func (a *Attributes) Equal(o *Attributes) bool { | ||
|  | 	if a == nil && o == nil { | ||
|  | 		return true | ||
|  | 	} | ||
|  | 	if a == nil || o == nil { | ||
|  | 		return false | ||
|  | 	} | ||
|  | 	if len(a.m) != len(o.m) { | ||
|  | 		return false | ||
|  | 	} | ||
|  | 	for k, v := range a.m { | ||
|  | 		ov, ok := o.m[k] | ||
|  | 		if !ok { | ||
|  | 			// o missing element of a | ||
|  | 			return false | ||
|  | 		} | ||
|  | 		if eq, ok := v.(interface{ Equal(o interface{}) bool }); ok { | ||
|  | 			if !eq.Equal(ov) { | ||
|  | 				return false | ||
|  | 			} | ||
|  | 		} else if v != ov { | ||
|  | 			// Fallback to a standard equality check if Value is unimplemented. | ||
|  | 			return false | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return true | ||
|  | } |