mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 21:02:24 -06: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
							 | 
						||
| 
								 | 
							
								}
							 |