pub struct Identifier { /* private fields */ }Expand description
A parsed SIN token: a player’s identity at the level of notation.
An Identifier bundles the two attributes a token encodes — a Letter
abbreviation and a Side — into a single 2-byte Copy value.
Construction from typed components via Identifier::new is total: every
combination is a valid token, so it cannot fail.
The derived total ordering compares attributes in the order letter → side.
§Examples
use sashite_sin::{Identifier, Side};
let chinese: Identifier = "c".parse()?;
assert_eq!(chinese.letter().as_char(), 'C');
assert_eq!(chinese.side(), Side::Second);
assert_eq!(chinese.to_char(), 'c');
// Transformations are cheap and infallible; the value is `Copy`.
assert_eq!(chinese.flipped().to_char(), 'C');Implementations§
Source§impl Identifier
impl Identifier
Sourcepub const fn new(letter: Letter, side: Side) -> Self
pub const fn new(letter: Letter, side: Side) -> Self
Builds an identifier from its two typed components.
This is infallible: because each component type is valid by construction, every combination denotes a valid SIN token.
§Examples
use sashite_sin::{Identifier, Letter, Side};
let p = Identifier::new(Letter::try_from_char('C').unwrap(), Side::Second);
assert_eq!(p.encode().as_str(), "c");Sourcepub const fn parse(input: &str) -> Result<Self, ParseError>
pub const fn parse(input: &str) -> Result<Self, ParseError>
Parses a string slice into an identifier.
The whole input must be the token: there is no leading or trailing slack, so surrounding whitespace, a trailing line break or any second character is a rejection rather than something to be trimmed away. The 52 tokens accepted here are the entire domain.
§Errors
Returns ParseError::Empty for an empty input, ParseError::TooLong
if input is two bytes or longer, and ParseError::InvalidLetter if
it is a single byte that is not an ASCII letter. Length is counted in
bytes, so a lone non-ASCII character is TooLong; see ParseError for
why that split is where it is.
§Examples
use sashite_sin::Identifier;
let western = Identifier::parse("W")?;
assert!(western.is_first());
assert_eq!(western.letter().as_char(), 'W');
// Nothing is trimmed, and a line break is never absorbed.
assert!(Identifier::parse(" W").is_err());
assert!(Identifier::parse("W\n").is_err());Sourcepub const fn is_valid(input: &str) -> bool
pub const fn is_valid(input: &str) -> bool
Reports whether input is a valid SIN token, without allocating or
constructing an identifier on the caller’s side.
This answers exactly the question Identifier::parse answers — it is
defined as that call succeeding — so the two can never disagree about
what a token is.
§Examples
use sashite_sin::Identifier;
assert!(Identifier::is_valid("S"));
assert!(Identifier::is_valid("s"));
assert!(!Identifier::is_valid("SS"));
assert!(!Identifier::is_valid(""));Sourcepub const fn encode(self) -> EncodedSin
pub const fn encode(self) -> EncodedSin
Returns the canonical, allocation-free string encoding of this token.
Sourcepub const fn to_char(self) -> char
pub const fn to_char(self) -> char
Returns the token as its single cased character: uppercase for
Side::First, lowercase for Side::Second.
§Examples
use sashite_sin::Identifier;
assert_eq!(Identifier::parse("J")?.to_char(), 'J');
assert_eq!(Identifier::parse("j")?.to_char(), 'j');Sourcepub const fn is_first(self) -> bool
pub const fn is_first(self) -> bool
Reports whether the side is Side::First.
Sourcepub const fn is_second(self) -> bool
pub const fn is_second(self) -> bool
Reports whether the side is Side::Second.
Sourcepub const fn with_letter(self, letter: Letter) -> Self
pub const fn with_letter(self, letter: Letter) -> Self
Returns a copy with the abbreviation replaced.
Trait Implementations§
Source§impl Clone for Identifier
impl Clone for Identifier
Source§fn clone(&self) -> Identifier
fn clone(&self) -> Identifier
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for Identifier
Source§impl Debug for Identifier
impl Debug for Identifier
Source§impl<'de> Deserialize<'de> for Identifier
impl<'de> Deserialize<'de> for Identifier
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl Display for Identifier
impl Display for Identifier
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Writes the canonical token — the single cased abbreviation letter.
The token goes out through core::fmt::Formatter::pad rather than
straight to the underlying buffer, so width, fill, alignment and
precision behave exactly as they do for the equivalent str. Writing
directly would silently discard those options, which matters as soon as
a token is placed in a fixed-width column.
impl Eq for Identifier
Source§impl FromStr for Identifier
impl FromStr for Identifier
Source§impl Hash for Identifier
impl Hash for Identifier
Source§impl Ord for Identifier
impl Ord for Identifier
Source§fn cmp(&self, other: &Identifier) -> Ordering
fn cmp(&self, other: &Identifier) -> Ordering
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialEq for Identifier
impl PartialEq for Identifier
Source§impl PartialOrd for Identifier
impl PartialOrd for Identifier
Source§impl Serialize for Identifier
impl Serialize for Identifier
impl StructuralPartialEq for Identifier
Source§impl TryFrom<&[u8]> for Identifier
impl TryFrom<&[u8]> for Identifier
Source§fn try_from(bytes: &[u8]) -> Result<Self, Self::Error>
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error>
Parses a token straight from raw bytes, for callers holding a network
or file buffer rather than a &str.
No UTF-8 validation happens, and none is needed: a token is a single
ASCII byte, so ill-formed input simply fails the same length and letter
checks every other entry point applies. This never disagrees with
Identifier::parse on bytes that are valid UTF-8, and it accepts
nothing that parse would reject.
§Errors
The same variants as Identifier::parse, decided the same way. Being
ill-formed is not itself a reason and gets no variant of its own; the
input is judged on its length exactly as text would be. A lone 0xFF is
ParseError::InvalidLetter because it is one byte that is not a
letter, and any two bytes are ParseError::TooLong whether or not
they decode.
§Examples
use sashite_sin::{Identifier, ParseError};
assert_eq!(Identifier::try_from(&b"W"[..]).unwrap().to_char(), 'W');
// Not UTF-8, and rejected without a panic or a separate error kind.
assert_eq!(Identifier::try_from(&[0xFF][..]), Err(ParseError::InvalidLetter));
assert_eq!(Identifier::try_from(&[0xC3][..]), Err(ParseError::InvalidLetter));
assert_eq!(Identifier::try_from(&[0xC3, 0xA9][..]), Err(ParseError::TooLong));