uuid
uuid/uuid.go
Add Copy() and IsZero() methods as helpers. Use id.Copy() to return a copy of the ID that shares nothing with the source ID. id.IsZero() returns true if the ID is equivalent to the zero value for the type.
| paddy@0 | 1 package uuid |
| paddy@0 | 2 |
| paddy@0 | 3 import ( |
| paddy@0 | 4 "database/sql/driver" |
| paddy@0 | 5 "encoding/json" |
| paddy@1 | 6 "encoding/xml" |
| paddy@0 | 7 "errors" |
| paddy@0 | 8 |
| paddy@0 | 9 "code.google.com/p/go-uuid/uuid" |
| paddy@0 | 10 ) |
| paddy@0 | 11 |
| paddy@0 | 12 var InvalidIDError = errors.New("Invalid ID format.") |
| paddy@0 | 13 |
| paddy@0 | 14 type ID uuid.UUID |
| paddy@0 | 15 |
| paddy@0 | 16 func NewID() ID { |
| paddy@0 | 17 return ID(uuid.NewRandom()) |
| paddy@0 | 18 } |
| paddy@0 | 19 |
| paddy@2 | 20 func (id ID) String() string { |
| paddy@2 | 21 return uuid.UUID(id).String() |
| paddy@2 | 22 } |
| paddy@2 | 23 |
| paddy@4 | 24 func (id ID) IsZero() bool { |
| paddy@4 | 25 if id == nil { |
| paddy@4 | 26 return true |
| paddy@4 | 27 } |
| paddy@4 | 28 if len(id) == 0 { |
| paddy@4 | 29 return true |
| paddy@4 | 30 } |
| paddy@4 | 31 return false |
| paddy@4 | 32 } |
| paddy@4 | 33 |
| paddy@4 | 34 func (id ID) Copy() ID { |
| paddy@4 | 35 resp, _ := Parse(id.String()) |
| paddy@4 | 36 // ignore the error because they asked for a copy of the ID, they |
| paddy@4 | 37 // never asked if it was valid or not. |
| paddy@4 | 38 // This is, overall, not the most efficient way to do this (we're |
| paddy@4 | 39 // essentially converting to a string and then back again) but the |
| paddy@4 | 40 // computational complexity involved is pretty minor, and it allows |
| paddy@4 | 41 // us to respect the boundaries between the packages, using only the |
| paddy@4 | 42 // exported interfaces to perform a copy. And that seems pretty |
| paddy@4 | 43 // valuable. |
| paddy@4 | 44 return resp |
| paddy@4 | 45 } |
| paddy@4 | 46 |
| paddy@0 | 47 func (id ID) MarshalJSON() ([]byte, error) { |
| paddy@0 | 48 return json.Marshal(id.String()) |
| paddy@0 | 49 } |
| paddy@0 | 50 |
| paddy@1 | 51 func (id ID) MarshalXML(e *xml.Encoder, start xml.StartElement) error { |
| paddy@1 | 52 return e.EncodeElement(id.String(), start) |
| paddy@1 | 53 } |
| paddy@1 | 54 |
| paddy@0 | 55 func (id ID) Value() (driver.Value, error) { |
| paddy@0 | 56 return id.String(), nil |
| paddy@0 | 57 } |
| paddy@0 | 58 |
| paddy@0 | 59 func (id *ID) Scan(src interface{}) error { |
| paddy@0 | 60 if src == nil { |
| paddy@0 | 61 id = nil |
| paddy@0 | 62 return nil |
| paddy@0 | 63 } |
| paddy@0 | 64 switch src.(type) { |
| paddy@0 | 65 case []byte: |
| paddy@3 | 66 if len(src.([]byte)) == 0 { |
| paddy@3 | 67 *id = (*id)[:0] |
| paddy@3 | 68 return nil |
| paddy@3 | 69 } |
| paddy@0 | 70 newID, err := Parse(string(src.([]byte))) |
| paddy@2 | 71 if err != nil { |
| paddy@2 | 72 return err |
| paddy@2 | 73 } |
| paddy@0 | 74 *id = append((*id)[:0], newID...) |
| paddy@2 | 75 return nil |
| paddy@0 | 76 case string: |
| paddy@3 | 77 if len(src.(string)) == 0 { |
| paddy@3 | 78 *id = (*id)[:0] |
| paddy@3 | 79 return nil |
| paddy@3 | 80 } |
| paddy@0 | 81 newID, err := Parse(src.(string)) |
| paddy@2 | 82 if err != nil { |
| paddy@2 | 83 return err |
| paddy@2 | 84 } |
| paddy@0 | 85 *id = append((*id)[:0], newID...) |
| paddy@2 | 86 return nil |
| paddy@0 | 87 default: |
| paddy@0 | 88 return InvalidIDError |
| paddy@0 | 89 } |
| paddy@0 | 90 return nil |
| paddy@0 | 91 } |
| paddy@0 | 92 |
| paddy@0 | 93 func (id *ID) UnmarshalJSON(in []byte) error { |
| paddy@0 | 94 var tmp string |
| paddy@0 | 95 err := json.Unmarshal(in, &tmp) |
| paddy@0 | 96 if err != nil { |
| paddy@0 | 97 return err |
| paddy@0 | 98 } |
| paddy@0 | 99 newID, err := Parse(tmp) |
| paddy@0 | 100 if err != nil { |
| paddy@0 | 101 return err |
| paddy@0 | 102 } |
| paddy@0 | 103 *id = append((*id)[:0], newID...) |
| paddy@0 | 104 return nil |
| paddy@0 | 105 } |
| paddy@0 | 106 |
| paddy@1 | 107 func (id *ID) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { |
| paddy@1 | 108 var tmp string |
| paddy@1 | 109 err := d.DecodeElement(&tmp, &start) |
| paddy@1 | 110 if err != nil { |
| paddy@1 | 111 return err |
| paddy@1 | 112 } |
| paddy@1 | 113 newID, err := Parse(tmp) |
| paddy@1 | 114 if err != nil { |
| paddy@1 | 115 return err |
| paddy@1 | 116 } |
| paddy@1 | 117 *id = append((*id)[:0], newID...) |
| paddy@1 | 118 return nil |
| paddy@1 | 119 } |
| paddy@1 | 120 |
| paddy@0 | 121 func Parse(in string) (ID, error) { |
| paddy@2 | 122 id := ID(uuid.Parse(in)) |
| paddy@2 | 123 if id == nil { |
| paddy@2 | 124 return id, InvalidIDError |
| paddy@0 | 125 } |
| paddy@2 | 126 return id, nil |
| paddy@0 | 127 } |
| paddy@0 | 128 |
| paddy@0 | 129 func (id ID) Equal(other ID) bool { |
| paddy@0 | 130 return uuid.Equal(uuid.UUID(id), uuid.UUID(other)) |
| paddy@0 | 131 } |