// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package uuid

import (
	
	
)

// FromBytes returns a UUID generated from the raw byte slice input.
// It will return an error if the slice isn't 16 bytes long.
func ( []byte) (UUID, error) {
	 := UUID{}
	 := .UnmarshalBinary()
	return , 
}

// FromBytesOrNil returns a UUID generated from the raw byte slice input.
// Same behavior as FromBytes(), but returns uuid.Nil instead of an error.
func ( []byte) UUID {
	,  := FromBytes()
	if  != nil {
		return Nil
	}
	return 
}

var errInvalidFormat = errors.New("uuid: invalid UUID format")

func fromHexChar( byte) byte {
	switch {
	case '0' <=  &&  <= '9':
		return  - '0'
	case 'a' <=  &&  <= 'f':
		return  - 'a' + 10
	case 'A' <=  &&  <= 'F':
		return  - 'A' + 10
	}
	return 255
}

// Parse parses the UUID stored in the string text. Parsing and supported
// formats are the same as UnmarshalText.
func ( *UUID) ( string) error {
	switch len() {
	case 32: // hash
	case 36: // canonical
	case 34, 38:
		if [0] != '{' || [len()-1] != '}' {
			return fmt.Errorf("uuid: incorrect UUID format in string %q", )
		}
		 = [1 : len()-1]
	case 41, 45:
		if [:9] != "urn:uuid:" {
			return fmt.Errorf("uuid: incorrect UUID format in string %q", [:9])
		}
		 = [9:]
	default:
		return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(), )
	}
	// canonical
	if len() == 36 {
		if [8] != '-' || [13] != '-' || [18] != '-' || [23] != '-' {
			return fmt.Errorf("uuid: incorrect UUID format in string %q", )
		}
		for ,  := range [16]byte{
			0, 2, 4, 6,
			9, 11,
			14, 16,
			19, 21,
			24, 26, 28, 30, 32, 34,
		} {
			 := fromHexChar([])
			 := fromHexChar([+1])
			if | == 255 {
				return errInvalidFormat
			}
			[] = ( << 4) | 
		}
		return nil
	}
	// hash like
	for  := 0;  < 32;  += 2 {
		 := fromHexChar([])
		 := fromHexChar([+1])
		if | == 255 {
			return errInvalidFormat
		}
		[/2] = ( << 4) | 
	}
	return nil
}

// FromString returns a UUID parsed from the input string.
// Input is expected in a form accepted by UnmarshalText.
func ( string) (UUID, error) {
	var  UUID
	 := .Parse()
	return , 
}

// FromStringOrNil returns a UUID parsed from the input string.
// Same behavior as FromString(), but returns uuid.Nil instead of an error.
func ( string) UUID {
	,  := FromString()
	if  != nil {
		return Nil
	}
	return 
}

// MarshalText implements the encoding.TextMarshaler interface.
// The encoding is the same as returned by the String() method.
func ( UUID) () ([]byte, error) {
	var  [36]byte
	encodeCanonical([:], )
	return [:], nil
}

// UnmarshalText implements the encoding.TextUnmarshaler interface.
// Following formats are supported:
//
//	"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
//	"{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
//	"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
//	"6ba7b8109dad11d180b400c04fd430c8"
//	"{6ba7b8109dad11d180b400c04fd430c8}",
//	"urn:uuid:6ba7b8109dad11d180b400c04fd430c8"
//
// ABNF for supported UUID text representation follows:
//
//	URN := 'urn'
//	UUID-NID := 'uuid'
//
//	hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
//	          'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
//	          'A' | 'B' | 'C' | 'D' | 'E' | 'F'
//
//	hexoct := hexdig hexdig
//	2hexoct := hexoct hexoct
//	4hexoct := 2hexoct 2hexoct
//	6hexoct := 4hexoct 2hexoct
//	12hexoct := 6hexoct 6hexoct
//
//	hashlike := 12hexoct
//	canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
//
//	plain := canonical | hashlike
//	uuid := canonical | hashlike | braced | urn
//
//	braced := '{' plain '}' | '{' hashlike  '}'
//	urn := URN ':' UUID-NID ':' plain
func ( *UUID) ( []byte) error {
	switch len() {
	case 32: // hash
	case 36: // canonical
	case 34, 38:
		if [0] != '{' || [len()-1] != '}' {
			return fmt.Errorf("uuid: incorrect UUID format in string %q", )
		}
		 = [1 : len()-1]
	case 41, 45:
		if string([:9]) != "urn:uuid:" {
			return fmt.Errorf("uuid: incorrect UUID format in string %q", [:9])
		}
		 = [9:]
	default:
		return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(), )
	}
	if len() == 36 {
		if [8] != '-' || [13] != '-' || [18] != '-' || [23] != '-' {
			return fmt.Errorf("uuid: incorrect UUID format in string %q", )
		}
		for ,  := range [16]byte{
			0, 2, 4, 6,
			9, 11,
			14, 16,
			19, 21,
			24, 26, 28, 30, 32, 34,
		} {
			 := fromHexChar([])
			 := fromHexChar([+1])
			if | == 255 {
				return errInvalidFormat
			}
			[] = ( << 4) | 
		}
		return nil
	}
	for  := 0;  < 32;  += 2 {
		 := fromHexChar([])
		 := fromHexChar([+1])
		if | == 255 {
			return errInvalidFormat
		}
		[/2] = ( << 4) | 
	}
	return nil
}

// MarshalBinary implements the encoding.BinaryMarshaler interface.
func ( UUID) () ([]byte, error) {
	return .Bytes(), nil
}

// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
// It will return an error if the slice isn't 16 bytes long.
func ( *UUID) ( []byte) error {
	if len() != Size {
		return fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len())
	}
	copy([:], )

	return nil
}