git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/container/id/id.go (about)

     1  package cid
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"fmt"
     6  
     7  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
     8  	"github.com/mr-tron/base58"
     9  )
    10  
    11  // ID represents FrostFS container identifier.
    12  //
    13  // ID is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs.ContainerID
    14  // message. See ReadFromV2 / WriteToV2 methods.
    15  //
    16  // Instances can be created using built-in var declaration.
    17  //
    18  // Note that direct typecast is not safe and may result in loss of compatibility:
    19  //
    20  //	_ = ID([32]byte) // not recommended
    21  type ID [sha256.Size]byte
    22  
    23  // ReadFromV2 reads ID from the refs.ContainerID message.
    24  // Returns an error if the message is malformed according
    25  // to the FrostFS API V2 protocol.
    26  //
    27  // See also WriteToV2.
    28  func (id *ID) ReadFromV2(m refs.ContainerID) error {
    29  	return id.Decode(m.GetValue())
    30  }
    31  
    32  // WriteToV2 writes ID to the refs.ContainerID message.
    33  // The message must not be nil.
    34  //
    35  // See also ReadFromV2.
    36  func (id ID) WriteToV2(m *refs.ContainerID) {
    37  	m.SetValue(id[:])
    38  }
    39  
    40  // Encode encodes ID into 32 bytes of dst. Panics if
    41  // dst length is less than 32.
    42  //
    43  // Zero ID is all zeros.
    44  //
    45  // See also Decode.
    46  func (id ID) Encode(dst []byte) {
    47  	if l := len(dst); l < sha256.Size {
    48  		panic(fmt.Sprintf("destination length is less than %d bytes: %d", sha256.Size, l))
    49  	}
    50  
    51  	copy(dst, id[:])
    52  }
    53  
    54  // Decode decodes src bytes into ID.
    55  //
    56  // Decode expects that src has 32 bytes length. If the input is malformed,
    57  // Decode returns an error describing format violation. In this case ID
    58  // remains unchanged.
    59  //
    60  // Decode doesn't mutate src.
    61  //
    62  // See also Encode.
    63  func (id *ID) Decode(src []byte) error {
    64  	if len(src) != sha256.Size {
    65  		return fmt.Errorf("invalid length %d", len(src))
    66  	}
    67  
    68  	copy(id[:], src)
    69  
    70  	return nil
    71  }
    72  
    73  // SetSHA256 sets container identifier value to SHA256 checksum of container structure.
    74  func (id *ID) SetSHA256(v [sha256.Size]byte) {
    75  	copy(id[:], v[:])
    76  }
    77  
    78  // Equals defines a comparison relation between two ID instances.
    79  //
    80  // Note that comparison using '==' operator is not recommended since it MAY result
    81  // in loss of compatibility.
    82  func (id ID) Equals(id2 ID) bool {
    83  	return id == id2
    84  }
    85  
    86  // EncodeToString encodes ID into FrostFS API protocol string.
    87  //
    88  // Zero ID is base58 encoding of 32 zeros.
    89  //
    90  // See also DecodeString.
    91  func (id ID) EncodeToString() string {
    92  	return base58.Encode(id[:])
    93  }
    94  
    95  // DecodeString decodes string into ID according to FrostFS API protocol. Returns
    96  // an error if s is malformed.
    97  //
    98  // See also DecodeString.
    99  func (id *ID) DecodeString(s string) error {
   100  	data, err := base58.Decode(s)
   101  	if err != nil {
   102  		return fmt.Errorf("decode base58: %w", err)
   103  	}
   104  
   105  	return id.Decode(data)
   106  }
   107  
   108  // String implements fmt.Stringer.
   109  //
   110  // String is designed to be human-readable, and its format MAY differ between
   111  // SDK versions. String MAY return same result as EncodeToString. String MUST NOT
   112  // be used to encode ID into FrostFS protocol string.
   113  func (id ID) String() string {
   114  	return id.EncodeToString()
   115  }