pub trait SubsetOf<T: ?Sized> { }Expand description
A type that suggests that one syntax rule is the subset of another.
This type is really only sensible on either the Profile or Delimiter
types. It doesn’t do anything for Boundary or Segmentation.
Implementing this incorrectly cannot lead to memory issues, but it can lead to incorrect logic that will do things you don’t expect (like identifying a string as an identifier format that it is not).
It’s valid to not implement this trait if you aren’t certain, it just prevents certain zero-cost casts from being possible.
§Burden of Proof
While it’s not an unsafe trait itself, since it’s tricky and easy to get
wrong, it’s highly recommended that each implementation of SubsetOf
demonstrates why that implementation is sane.
The format of this is “Proof: (Brief Reason)”, and then it can be followed-up with more details if necessary to make the reason clearer. See some of the implementations of this trait in this crate as an example.
§Always Sane: SubsetOf<Self>
It is always sane (and recommended) to implement this against yourself. We don’t do this by default to leave the generic impl space open for more complex generic impls.
impl SubsetOf<T> for T {}
For more complex cases…
You can implement this when the validation property of a syntax rule are
all supersets (or equal-to) the validation properties of your defined
syntax (here, referred to as Self).
For Delimiter, you can implement SubsetOf<Super> if:
Self::is_ident_start⊆Super::is_ident_start, and…Self::is_chunk_delim⊆Super::is_chunk_delim
For Profile, you can implement SubsetOf<Super> if:
Self::is_ident_start⊆Super::is_ident_start, and…Self::is_chunk_start⊆Super::is_chunk_start, and…Self::is_chunk_continue⊆Super::is_chunk_continue
Another way to say this is:
For any character that returns true for a function, you can call the same
function in the prospective Super type and also get true - then
Self: SubsetOf<Super>.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl SubsetOf<Ascii> for Ascii
Proof: It’s always safe to implement this against yourself.
impl SubsetOf<AsciiFlatLine> for AsciiFlatLine
Proof: It’s always safe to implement this against yourself.
impl SubsetOf<AsciiFlatLine> for HyphenMinus
Proof: AsciiFlatLine very obviously contains a flat-line symbol (‘_’ or ‘-’).
impl SubsetOf<AsciiFlatLine> for LowLine
Proof: AsciiFlatLine very obviously contains a flat-line symbol (‘_’ or ‘-’).
impl SubsetOf<AsciiPunctuation> for AsciiFlatLine
Proof: AsciiPunctuation very obviously contains AsciiFlatLine (‘_’, ‘-’).
impl SubsetOf<AsciiPunctuation> for AsciiPunctuation
Proof: It’s always safe to implement this against yourself.
impl SubsetOf<AsciiPunctuation> for HyphenMinus
Proof: AsciiPunctuation very obviously contains a flat-line symbol (‘_’ or ‘-’).
impl SubsetOf<AsciiPunctuation> for LowLine
Proof: AsciiPunctuation very obviously contains a flat-line symbol (‘_’ or ‘-’).
impl SubsetOf<HyphenMinus> for HyphenMinus
Proof: It’s always safe to implement this against yourself.
impl SubsetOf<LowLine> for LowLine
Proof: It’s always safe to implement this against yourself.
impl SubsetOf<Strict> for Ascii
Proof: ASCII is a subset of the Strict profile (which is basically Unicode).
impl SubsetOf<Strict> for Strict
Proof: It’s always safe to implement this against yourself.
impl SubsetOf<Unicode> for Ascii
Proof: ASCII is an obvious subset of Unicode.
impl SubsetOf<Unicode> for Strict
Proof: Strict is a subset of the Unicode profile (strict has more restrictions).
impl SubsetOf<Unicode> for Unicode
Proof: It’s always safe to implement this against yourself.
impl<Superset, Subset> SubsetOf<Lower<Superset>> for Lower<Subset>
Proof: If Super ⊆ Subset, then Lower<Super> ⊆ Lower<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
Lower<Ascii>: SubsetOf<Lower<Unicode>>
§Proof
left_is_subset_of_right::<Lower<Ascii>, Lower<Ascii>>();
left_is_subset_of_right::<Lower<Unicode>, Lower<Unicode>>();
left_is_subset_of_right::<Lower<Ascii>, Lower<Unicode>>();impl<Superset, Subset> SubsetOf<LowerCamel<Superset>> for Lower<Subset>
Proof: If Super ⊆ Subset, then LowerCamel<Super> ⊆ Lower<Subset>
(because LowerCamel ⊆ Lower).
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
Lower<Ascii>: SubsetOf<LowerCamel<Unicode>>
§Proof
left_is_subset_of_right::<Lower<Ascii>, LowerCamel<Ascii>>();
left_is_subset_of_right::<Lower<Unicode>, LowerCamel<Unicode>>();
left_is_subset_of_right::<Lower<Ascii>, LowerCamel<Unicode>>();impl<Superset, Subset> SubsetOf<LowerCamel<Superset>> for LowerCamel<Subset>
Proof: If Super ⊆ Subset, then LowerCamel<Super> ⊆ LowerCamel<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
LowerCamel<Ascii>: SubsetOf<LowerCamel<Unicode>>
§Proof
left_is_subset_of_right::<LowerCamel<Ascii>, LowerCamel<Ascii>>();
left_is_subset_of_right::<LowerCamel<Unicode>, LowerCamel<Unicode>>();
left_is_subset_of_right::<LowerCamel<Ascii>, LowerCamel<Unicode>>();impl<Superset, Subset> SubsetOf<Superset> for Lower<Subset>
Proof: If Super ⊆ Subset, then Super ⊆ Lower<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
Lower<Ascii>: SubsetOf<Unicode>
§Proof
left_is_subset_of_right::<Lower<Ascii>, Ascii>();
left_is_subset_of_right::<Lower<Unicode>, Unicode>();
left_is_subset_of_right::<Lower<Ascii>, Unicode>();impl<Superset, Subset> SubsetOf<Superset> for LowerCamel<Subset>
Proof: If Super ⊆ Subset, then Super ⊆ LowerCamel<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
LowerCamel<Ascii>: SubsetOf<Unicode>
§Proof
left_is_subset_of_right::<LowerCamel<Ascii>, Ascii>();
left_is_subset_of_right::<LowerCamel<Unicode>, Unicode>();
left_is_subset_of_right::<LowerCamel<Ascii>, Unicode>();impl<Superset, Subset> SubsetOf<Superset> for Upper<Subset>
Proof: If Super ⊆ Subset, then Super ⊆ Upper<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
Upper<Ascii>: SubsetOf<Unicode>
§Examples
left_is_subset_of_right::<Upper<Ascii>, Ascii>();
left_is_subset_of_right::<Upper<Unicode>, Unicode>();
left_is_subset_of_right::<Upper<Ascii>, Unicode>();impl<Superset, Subset> SubsetOf<Superset> for UpperCamel<Subset>
Proof: If Super ⊆ Subset, then Super ⊆ UpperCamel<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
UpperCamel<Ascii>: SubsetOf<Unicode>
§Proof
left_is_subset_of_right::<UpperCamel<Ascii>, Ascii>();
left_is_subset_of_right::<UpperCamel<Unicode>, Unicode>();
left_is_subset_of_right::<UpperCamel<Ascii>, Unicode>();impl<Superset, Subset> SubsetOf<Upper<Superset>> for Upper<Subset>
Proof: if Super ⊆ Subset, then Upper<Super> ⊆ Upper<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
Upper<Ascii>: SubsetOf<Upper<Unicode>>
§Examples
left_is_subset_of_right::<Upper<Ascii>, Upper<Ascii>>();
left_is_subset_of_right::<Upper<Unicode>, Upper<Unicode>>();
left_is_subset_of_right::<Upper<Ascii>, Upper<Unicode>>();impl<Superset, Subset> SubsetOf<UpperCamel<Superset>> for Upper<Subset>
Proof: If Super ⊆ Subset, then UpperCamel<Super> ⊆ Upper<Subset>
(because UpperCamel ⊆ Upper).
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
Upper<Ascii>: SubsetOf<UpperCamel<Unicode>>
§Examples
left_is_subset_of_right::<Upper<Ascii>, UpperCamel<Ascii>>();
left_is_subset_of_right::<Upper<Unicode>, UpperCamel<Unicode>>();
left_is_subset_of_right::<Upper<Ascii>, UpperCamel<Unicode>>();impl<Superset, Subset> SubsetOf<UpperCamel<Superset>> for UpperCamel<Subset>
Proof: If Super ⊆ Subset, then UpperCamel<Super> ⊆ UpperCamel<Subset>.
Let’s pretend that Superset=Unicode, and Subset=Ascii.
If Ascii: SubsetOf<Unicode> (true), then this implies the following:
UpperCamel<Ascii>: SubsetOf<UpperCamel<Unicode>>
§Proof
left_is_subset_of_right::<UpperCamel<Ascii>, UpperCamel<Ascii>>();
left_is_subset_of_right::<UpperCamel<Unicode>, UpperCamel<Unicode>>();
left_is_subset_of_right::<UpperCamel<Ascii>, UpperCamel<Unicode>>();