1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! Errors produced when parsing a SIN token.
/// The reason a string could not be parsed as a SIN token.
///
/// Returned by the parsing entry points ([`crate::Identifier::parse`],
/// [`core::str::FromStr`], [`TryFrom`]) and by [`crate::Letter::try_from_char`].
///
/// This enum is `#[non_exhaustive]`: future revisions may add variants without
/// a breaking change, so downstream `match` expressions should include a
/// wildcard arm.
///
/// # Length is measured in bytes
///
/// A valid token is one ASCII letter, which is always exactly one byte, so the
/// parser can decide on the byte length before looking at any content. The
/// consequence is worth knowing when reading the variant back: an input of one
/// *character* that occupies several *bytes* — any non-ASCII character, such as
/// `é` — is reported as [`TooLong`](Self::TooLong), not as
/// [`InvalidLetter`](Self::InvalidLetter). Both say "this is not a token", and
/// the specification requires only that such input be rejected; only the
/// reported reason differs.
///
/// The rule is exact: [`InvalidLetter`](Self::InvalidLetter) means the input
/// was one byte that was not an ASCII letter, and [`TooLong`](Self::TooLong)
/// means it was two bytes or more.
///
/// # Examples
///
/// ```
/// use sashite_sin::{Identifier, ParseError};
///
/// assert_eq!("".parse::<Identifier>(), Err(ParseError::Empty));
/// assert_eq!("CC".parse::<Identifier>(), Err(ParseError::TooLong));
/// assert_eq!("1".parse::<Identifier>(), Err(ParseError::InvalidLetter));
///
/// // One character, two bytes: rejected as too long.
/// assert_eq!("é".chars().count(), 1);
/// assert_eq!("é".parse::<Identifier>(), Err(ParseError::TooLong));
/// ```