@@ -186,6 +186,59 @@ func Must(uuid UUID, err error) UUID {
186
186
return uuid
187
187
}
188
188
189
+ // Validate returns an error if s is not a properly formatted UUID in one of the following formats:
190
+ // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
191
+ // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
192
+ // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
193
+ // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
194
+ // It returns an error if the format is invalid, otherwise nil.
195
+ func Validate (s string ) error {
196
+ switch len (s ) {
197
+ // Standard UUID format
198
+ case 36 :
199
+
200
+ // UUID with "urn:uuid:" prefix
201
+ case 36 + 9 :
202
+ if ! strings .EqualFold (s [:9 ], "urn:uuid:" ) {
203
+ return fmt .Errorf ("invalid urn prefix: %q" , s [:9 ])
204
+ }
205
+ s = s [9 :]
206
+
207
+ // UUID enclosed in braces
208
+ case 36 + 2 :
209
+ if s [0 ] != '{' || s [len (s )- 1 ] != '}' {
210
+ return fmt .Errorf ("invalid bracketed UUID format" )
211
+ }
212
+ s = s [1 : len (s )- 1 ]
213
+
214
+ // UUID without hyphens
215
+ case 32 :
216
+ for i := 0 ; i < len (s ); i += 2 {
217
+ _ , ok := xtob (s [i ], s [i + 1 ])
218
+ if ! ok {
219
+ return errors .New ("invalid UUID format" )
220
+ }
221
+ }
222
+
223
+ default :
224
+ return invalidLengthError {len (s )}
225
+ }
226
+
227
+ // Check for standard UUID format
228
+ if len (s ) == 36 {
229
+ if s [8 ] != '-' || s [13 ] != '-' || s [18 ] != '-' || s [23 ] != '-' {
230
+ return errors .New ("invalid UUID format" )
231
+ }
232
+ for _ , x := range []int {0 , 2 , 4 , 6 , 9 , 11 , 14 , 16 , 19 , 21 , 24 , 26 , 28 , 30 , 32 , 34 } {
233
+ if _ , ok := xtob (s [x ], s [x + 1 ]); ! ok {
234
+ return errors .New ("invalid UUID format" )
235
+ }
236
+ }
237
+ }
238
+
239
+ return nil
240
+ }
241
+
189
242
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
190
243
// , or "" if uuid is invalid.
191
244
func (uuid UUID ) String () string {
0 commit comments