pub struct CharPartition { /* private fields */ }Expand description
Collection of disjoint character sets.
Each character set is an interval [a, b] where a <= b.
The character sets are sorted in increasing order so a partition of length n is a sequence
[a0, b0], [a1, b1], …, [an-1, bn-1] where ai <= bi and bi < ai+1.
This divides the alphabet into n+1 classes C0, …, Cn-1, and D:
- Ci = { x | ai <= x <= bi }
- D = complement of Union(C0, …, Cn-1)
Each class in a partition can be identified by its ClassId:
ClassId::Interval(i)denotes the class Ci, that is, the interval [ai, bi].ClassId::Complementdenotes the complementary class D.
Implementations§
Source§impl CharPartition
impl CharPartition
Sourcepub fn from_set(c: &CharSet) -> Self
pub fn from_set(c: &CharSet) -> Self
Partition with a single character set
§Example
use aws_smt_strings::character_sets::*;
let p = CharPartition::from_set(&CharSet::range('a' as u32, 'b' as u32));
assert_eq!(p.len(), 1);
assert_eq!(p.get(0), ('a' as u32, 'b' as u32))Sourcepub fn try_from_iter(iter: impl Iterator<Item = CharSet>) -> Result<Self, Error>
pub fn try_from_iter(iter: impl Iterator<Item = CharSet>) -> Result<Self, Error>
Build a partition from a CharSet iterator
Succeeds if the CharSets are pairwise disjoint. Fails otherwise.
§Errors
If some CharSets have a non-empty intersection, return Err(Error::NonDisjointCharSets).
§Example
use aws_smt_strings::character_sets::*;
let v = [
CharSet::range(120, 400),
CharSet::range(0, 10),
CharSet::range(1000, 2000)];
let p = CharPartition::try_from_iter(v.into_iter().copied())?;
assert_eq!(p.len(), 3);
assert_eq!(p.get(0), (0, 10));
assert_eq!(p.get(1), (120, 400));
assert_eq!(p.get(2), (1000, 2000));Sourcepub fn try_from_list(a: &[CharSet]) -> Result<Self, Error>
pub fn try_from_list(a: &[CharSet]) -> Result<Self, Error>
Build a partition from a list of CharSets
Succeeds if the CharSets in a are pairwise disjoint.
Fails otherwise.
§Errors
If some elements of a have a non-empty intersection,
return Err(Error::NonDisjointCharSets).
§Example
use aws_smt_strings::character_sets::*;
let v = [
CharSet::range(120, 400),
CharSet::range(0, 10),
CharSet::range(1000, 2000)];
let p = CharPartition::try_from_list(&v)?;
assert_eq!(p.len(), 3);
assert_eq!(p.get(0), (0, 10));
assert_eq!(p.get(1), (120, 400));
assert_eq!(p.get(2), (1000, 2000));
Sourcepub fn push(&mut self, start: u32, end: u32)
pub fn push(&mut self, start: u32, end: u32)
Add the interval [start, end] at the end of the partition.
Requires start <= end and end <= MAX_CHAR.
If the partition is not empty, start must also be larger than the end of the
last interval in the partition.
§Example
This constructs the two-interval partition ['0', '9'] ['Z', 'Z'].
use aws_smt_strings::character_sets::*;
let mut p = CharPartition::new();
p.push('0' as u32, '9' as u32);
p.push('Z' as u32, 'Z' as u32);
assert_eq!(p.len(), 2);
assert_eq!(p.get(0), ('0' as u32, '9' as u32));
assert_eq!(p.get(1), ('Z' as u32, 'Z' as u32));Sourcepub fn get(&self, i: usize) -> (u32, u32)
pub fn get(&self, i: usize) -> (u32, u32)
Get the pair (start, end) of the i-the interval in the partition
Intervals are indexed from 0 to p.len() - 1 (inclusive).
- if i < p.len(), return the start and end of the i-th interval.
- if i >= p.len(), return the pair
(MAX_CHAR+1, MAX_CHAR+1)
§Example
use aws_smt_strings::character_sets::*;
use aws_smt_strings::smt_strings::MAX_CHAR;
// partition ['0', '9'] ['Z', 'Z']
let mut p = CharPartition::new();
p.push('0' as u32, '9' as u32);
p.push('Z' as u32, 'Z' as u32);
assert_eq!(p.get(0), ('0' as u32, '9' as u32)); // first interval
assert_eq!(p.get(3), (MAX_CHAR + 1, MAX_CHAR + 1)); // out-of-range indexSourcepub fn interval(&self, i: usize) -> CharSet
pub fn interval(&self, i: usize) -> CharSet
Get the i-the interval in the partition as a CharSet.
§Panics
If i is out of bound, that is, if i >= number of intervals in the partition.
§Example
use aws_smt_strings::character_sets::*;
let mut p = CharPartition::new();
p.push('a' as u32, 'z' as u32);
assert_eq!(p.interval(0), CharSet::range('a' as u32, 'z' as u32));Sourcepub fn start(&self, i: usize) -> u32
pub fn start(&self, i: usize) -> u32
Get the start of the i-th interval
- return
MAX_CHAR+1if i is out of bound.
§Example
use aws_smt_strings::character_sets::*;
use aws_smt_strings::smt_strings::MAX_CHAR;
let mut p = CharPartition::new();
p.push('a' as u32, 'z' as u32);
assert_eq!(p.start(0), 'a' as u32);
assert_eq!(p.start(1), MAX_CHAR+1);Sourcepub fn end(&self, index: usize) -> u32
pub fn end(&self, index: usize) -> u32
Get the end of the i-th interval
- return
MAX_CHAR+1if i is out of bound
§Example
use aws_smt_strings::character_sets::*;
use aws_smt_strings::smt_strings::MAX_CHAR;
let mut p = CharPartition::new();
p.push('a' as u32, 'z' as u32);
assert_eq!(p.end(0), 'z' as u32);
assert_eq!(p.end(1), MAX_CHAR+1);Sourcepub fn empty_complement(&self) -> bool
pub fn empty_complement(&self) -> bool
Check whether the complementary class is empty
§Example
use aws_smt_strings::character_sets::*;
use aws_smt_strings::smt_strings::MAX_CHAR;
let mut p = CharPartition::new();
p.push(0, 127);
assert!(! p.empty_complement());
p.push(128, MAX_CHAR);
assert!(p.empty_complement());Sourcepub fn pick_complement(&self) -> u32
pub fn pick_complement(&self) -> u32
Pick an element in the complementary class
- return
MAX_CHAR+1if the complementary class is empty
§Example
use aws_smt_strings::character_sets::*;
use aws_smt_strings::smt_strings::MAX_CHAR;
// partition with a single interval ['a', 'z']
let p = CharPartition::from_set(&CharSet::range('a' as u32, 'z' as u32));
// the complementary class is the union of [0, 'a' - 1] and ['z' + 1, MAX_CHAR]
let x = p.pick_complement();
assert!(x < ('a' as u32) || ('z' as u32) < x && x <= MAX_CHAR);Sourcepub fn valid_class_id(&self, cid: ClassId) -> bool
pub fn valid_class_id(&self, cid: ClassId) -> bool
Check whether a class id is valid
§Example
use aws_smt_strings::character_sets::*;
// partition with two intervals and three classes
let mut p = CharPartition::new();
p.push('0' as u32, '9' as u32);
p.push('Z' as u32, 'Z' as u32);
assert!(p.valid_class_id(ClassId::Interval(0)));
assert!(p.valid_class_id(ClassId::Interval(1)));
assert!(p.valid_class_id(ClassId::Complement));
assert!(! p.valid_class_id(ClassId::Interval(2)));Sourcepub fn num_classes(&self) -> usize
pub fn num_classes(&self) -> usize
Number of classes
§Example
use aws_smt_strings::character_sets::*;
// partition with two intervals and three classes
let mut p = CharPartition::new();
p.push('0' as u32, '9' as u32);
p.push('Z' as u32, 'Z' as u32);
assert_eq!(p.num_classes(), 3);Sourcepub fn pick_in_class(&self, cid: ClassId) -> u32
pub fn pick_in_class(&self, cid: ClassId) -> u32
Pick an element in a class
- cid identifies the class: if cid = Interval(i) then pick in the i-th interval of p (intervals are indexed from 0 to p.len() - 1)
- if cid is Complement then pick in the complementary class
§Panics
If cid is Interval(i) and i >= p.len() or cid is Complement and the complementary class is empty.
§Example
use aws_smt_strings::character_sets::{ClassId::*, *};
use aws_smt_strings::smt_strings::MAX_CHAR;
let mut p = CharPartition::new();
p.push('0' as u32, '9' as u32);
p.push('Z' as u32, 'Z' as u32);
let x = p.pick_in_class(Interval(1));
assert_eq!(x, 'Z' as u32); // since interval 1 is ['Z', 'Z']
let y = p.pick_in_class(Complement);
assert!(0 <= y && y < ('0' as u32) ||
('9' as u32) < y && y < ('Z' as u32) ||
('Z' as u32) < y && y <= MAX_CHAR);Sourcepub fn ranges(&self) -> impl Iterator<Item = &CharSet>
pub fn ranges(&self) -> impl Iterator<Item = &CharSet>
Iterator to go through all intervals in the partition
Sourcepub fn class_ids(&self) -> ClassIdIterator<'_> ⓘ
pub fn class_ids(&self) -> ClassIdIterator<'_> ⓘ
Iterator to go through all valid class ids
Sourcepub fn picks(&self) -> PickIterator<'_> ⓘ
pub fn picks(&self) -> PickIterator<'_> ⓘ
Iterator to pick one character in each class (including the complementary class).
Sourcepub fn class_of_char(&self, x: u32) -> ClassId
pub fn class_of_char(&self, x: u32) -> ClassId
Search for the class that contains a character
- Return
Interval(i)ifa_i <= x <= b_i - Return
Complementif x is not in any interval
Sourcepub fn interval_cover(&self, set: &CharSet) -> CoverResult
pub fn interval_cover(&self, set: &CharSet) -> CoverResult
Search for an interval that covers a character set
The character set is an interval [a, b] where 0 <= a <= b <= MAX_CHAR.
- Return
CoverResult::CoveredBy(i)if [a, b] is included in the i-th interval of the partition. - Return
CoverResult::DisjointFromAllif [a, b] does not overlap any interval in the partition. - Return
CoverResult::Overlapsif [a, b] overlaps some interval in the partition but it not contained in this interval.
§Example
use aws_smt_strings::character_sets::*;
let p = CharPartition::from_set(&CharSet::range('0' as u32, '9' as u32));
let test1 = CharSet::range('4' as u32, '8' as u32);
let test2 = CharSet::range('a' as u32, 'z' as u32);
let test3 = CharSet::range('5' as u32, '?' as u32);
assert_eq!(p.interval_cover(&test1), CoverResult::CoveredBy(0));
assert_eq!(p.interval_cover(&test2), CoverResult::DisjointFromAll);
assert_eq!(p.interval_cover(&test3), CoverResult::Overlaps);Sourcepub fn class_of_set(&self, s: &CharSet) -> Result<ClassId, Error>
pub fn class_of_set(&self, s: &CharSet) -> Result<ClassId, Error>
Get the class id for a character set
- The class id is Interval(i) if the set is covered by interval [ai, bi] of the partition
- The class id is Complement if the set is covered by the partition’s complementary class
- Otherwise, the class id is not defined.
§Error
If the class id is not defined for s, return Err(Error::AmbiguousCharSet)
Sourcepub fn good_char_set(&self, c: &CharSet) -> bool
pub fn good_char_set(&self, c: &CharSet) -> bool
Check whether character set c is consistent with the partition.
- return true if c is included in one partition’s class or if c is included in the partition’s complementary class.
§Example
use aws_smt_strings::character_sets::*;
let p = CharPartition::from_set(&CharSet::range('0' as u32, '9' as u32));
let test1 = CharSet::range('4' as u32, '8' as u32);
let test2 = CharSet::range('a' as u32, 'z' as u32);
let test3 = CharSet::range('5' as u32, '?' as u32);
assert!(p.good_char_set(&test1));
assert!(p.good_char_set(&test2));
assert!(! p.good_char_set(&test3));Trait Implementations§
Source§impl Clone for CharPartition
impl Clone for CharPartition
Source§fn clone(&self) -> CharPartition
fn clone(&self) -> CharPartition
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more