All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 32s
				
			Test / Sandbox (push) Successful in 1m56s
				
			Test / Hakurei (push) Successful in 2m42s
				
			Test / Sandbox (race detector) (push) Successful in 3m5s
				
			Test / Planterette (push) Successful in 3m37s
				
			Test / Hakurei (race detector) (push) Successful in 4m19s
				
			Test / Flake checks (push) Successful in 1m7s
				
			It is completely nonsensical and highly error-prone to have multiple implementations of this in the same build. This should be switched at compile time instead therefore the split packages are pointless. Signed-off-by: Ophestra <cat@gensokyo.uk>
		
			
				
	
	
		
			49 lines
		
	
	
		
			667 B
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			49 lines
		
	
	
		
			667 B
		
	
	
	
		
			Go
		
	
	
	
	
	
| package state
 | |
| 
 | |
| import (
 | |
| 	"crypto/rand"
 | |
| 	"encoding/hex"
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| )
 | |
| 
 | |
| type ID [16]byte
 | |
| 
 | |
| var (
 | |
| 	ErrInvalidLength = errors.New("string representation must have a length of 32")
 | |
| )
 | |
| 
 | |
| func (a *ID) String() string {
 | |
| 	return hex.EncodeToString(a[:])
 | |
| }
 | |
| 
 | |
| func NewAppID(id *ID) error {
 | |
| 	_, err := rand.Read(id[:])
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func ParseAppID(id *ID, s string) error {
 | |
| 	if len(s) != 32 {
 | |
| 		return ErrInvalidLength
 | |
| 	}
 | |
| 
 | |
| 	for i, b := range s {
 | |
| 		if b < '0' || b > 'f' {
 | |
| 			return fmt.Errorf("invalid char %q at byte %d", b, i)
 | |
| 		}
 | |
| 
 | |
| 		v := uint8(b)
 | |
| 		if v > '9' {
 | |
| 			v = 10 + v - 'a'
 | |
| 		} else {
 | |
| 			v -= '0'
 | |
| 		}
 | |
| 		if i%2 == 0 {
 | |
| 			v <<= 4
 | |
| 		}
 | |
| 		id[i/2] += v
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 |