Skip to main content

typed_ident/syntax/
subset_of.rs

1// =============================================================================
2// TYPES
3// =============================================================================
4
5/// A type that suggests that one syntax rule is the subset of another.
6///
7/// This type is really only sensible on either the [`Profile`] or [`Delimiter`]
8/// types. It doesn't do anything for [`Boundary`] or [`Segmentation`].
9///
10/// Implementing this incorrectly cannot lead to memory issues, but it *can*
11/// lead to incorrect logic that will do things you don't expect (like
12/// identifying a string as an identifier format that it is not).
13///
14/// It's valid to *not* implement this trait if you aren't certain, it just
15/// prevents certain zero-cost casts from being possible.
16///
17/// # Burden of Proof
18///
19/// While it's not an unsafe trait itself, since it's tricky and easy to get
20/// wrong, it's highly recommended that each implementation of `SubsetOf`
21/// demonstrates why that implementation is sane.
22///
23/// The format of this is "Proof: (Brief Reason)", and then it can be
24/// followed-up with more details if necessary to make the reason clearer. See
25/// some of the implementations of this trait in this crate as an example.
26///
27/// # Always Sane: `SubsetOf<Self>`
28///
29/// It is *always* sane (and recommended) to implement this against yourself.
30/// We don't do this by default to leave the generic impl space open for more
31/// complex generic impls.
32///
33/// * `impl SubsetOf<T> for T {}`
34///
35/// For more complex cases...
36///
37/// You can implement this when the validation property of a syntax rule are
38/// *all* supersets (or equal-to) the validation properties of your defined
39/// syntax (here, referred to as `Self`).
40///
41/// For [`Delimiter`], you can implement `SubsetOf<Super>` if:
42///
43/// * `Self::is_ident_start` ⊆ `Super::is_ident_start`, *and...*
44/// * `Self::is_chunk_delim` ⊆ `Super::is_chunk_delim`
45///
46/// For [`Profile`], you can implement `SubsetOf<Super>` if:
47///
48/// * `Self::is_ident_start` ⊆ `Super::is_ident_start`, *and...*
49/// * `Self::is_chunk_start` ⊆ `Super::is_chunk_start`, *and...*
50/// * `Self::is_chunk_continue` ⊆ `Super::is_chunk_continue`
51///
52/// Another way to say this is:
53///
54/// For any character that returns `true` for a function, you can call the same
55/// function in the prospective `Super` type and *also* get `true` - then
56/// `Self: SubsetOf<Super>`.
57///
58/// [`Boundary`]: crate::syntax::boundary::Boundary
59/// [`Delimiter`]: crate::syntax::delimiter::Delimiter
60/// [`Profile`]: crate::syntax::profile::Profile
61/// [`Segmentation`]: crate::syntax::segmentation::Segmentation
62pub trait SubsetOf<T: ?Sized> {}