mtid 0.6.1

Human-friendly id for personal distributed system (deprecated, use the caretta-id crate)
Documentation
#[cfg(feature = "rusqlite")]
mod rusqlite;
#[cfg(feature = "sea-orm")]
mod sea_orm;

#[cfg(feature = "prost")]
use crate::macros;
use crate::{Error, Stid, alphabet::is_delimiter, dtid::Dtid, triplet::Triplet};

use core::{fmt::Display, str::FromStr};

crate::macros::mtid_struct! {
    Self = Ttid,
    ActualT = u64,
    description = "Triple length Triplet ID",
    example_str = "abc-def-ghj",
    example_int = 11386409697842,
}
crate::macros::mtid_impl! {
    Self = Ttid,
    Uint = u64,
    BITS = 45,
    CAPACITY = (Stid::CAPACITY as u64).pow(3),
    NIL_STR = "000-000-000",
    MAX_STR = "zzz-zzz-zzz",
    MAX_INT = 35184372088831,
    EXAMPLE_VALID_INT = 0b0000_0000_0000_0000_0000_1001_0001_1000_0100_1110_0111_0010_1010_0000_0000_0000,
    EXAMPLE_OVERSIZED_INT = 0b1111_1111_1111_1111_1110_1001_0001_1000_0100_1110_0111_0010_1010_0000_0000_0000
}

crate::macros::mtid_bytes_impl! {
    Self = Ttid,
    Uint = u64,
    LEN = 6,
}

impl Display for Ttid {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let tuple: (Triplet, Triplet, Triplet) = (*self).into();
        write!(f, "{}-{}-{}", tuple.0, tuple.1, tuple.2)
    }
}

impl FromStr for Ttid {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut chars = s.chars();
        let len = s.len();
        match len {
            9 | 11 => {
                let has_delimiter = len == 11;
                let first_triplet =
                    Triplet::parse_chars(&mut chars).map_err(|e| Error::ParseTriplet {
                        source: e,
                        index: 0,
                    })?;
                if has_delimiter {
                    let delimiter = chars.next().unwrap();
                    if !is_delimiter(delimiter) {
                        return Err(Error::ParseDelimiter {
                            character: delimiter,
                            index: 0,
                        });
                    }
                }
                let second_triplet =
                    Triplet::parse_chars(&mut chars).map_err(|e| Error::ParseTriplet {
                        source: e,
                        index: 1,
                    })?;
                if has_delimiter {
                    let delimiter = chars.next().unwrap();
                    if !is_delimiter(delimiter) {
                        return Err(Error::ParseDelimiter {
                            character: delimiter,
                            index: 1,
                        });
                    }
                }
                let third_triplet =
                    Triplet::parse_chars(&mut chars).map_err(|e| Error::ParseTriplet {
                        source: e,
                        index: 2,
                    })?;

                Ok(Self::from((first_triplet, second_triplet, third_triplet)))
            }
            x => Err(Error::ParseLength {
                expected_without_delimiter: 9,
                expected_with_delimiter: Some(11),
                found: x,
            }),
        }
    }
}

impl From<(Triplet, Triplet, Triplet)> for Ttid {
    fn from(value: (Triplet, Triplet, Triplet)) -> Self {
        Self(
            ((u16::from(value.0) as u64) << Dtid::BITS)
                | ((u16::from(value.1) as u64) << Stid::BITS)
                | (u16::from(value.2) as u64),
        )
    }
}

impl From<Ttid> for (Triplet, Triplet, Triplet) {
    fn from(value: Ttid) -> Self {
        (
            Triplet::from_uint_lossy((value.0 >> Dtid::BITS) as u16),
            Triplet::from_uint_lossy((value.0 >> Stid::BITS) as u16),
            Triplet::from_uint_lossy(value.0 as u16),
        )
    }
}

#[cfg(feature = "std")]
impl PartialEq<String> for Ttid {
    fn eq(&self, other: &String) -> bool {
        match Self::from_str(other) {
            Ok(x) => *self == x,
            Err(_) => false,
        }
    }
}

#[cfg(feature = "prost")]
macros::mtid_prost_impl! {
    Self = Ttid,
    ActualT = u64,
    ProtoT = proto::Ttid,
    BITS = 45,
    VALID_VALUE = 0b0000_0000_0000_0000_0000_1001_0001_1000_0100_1110_0111_0010_1010_0000_0000_0000,
    OVERSIZED_VALUE = 0b1111_1111_1111_1111_1110_1001_0001_1000_0100_1110_0111_0010_1010_0000_0000_0000,
}