Skip to main content

Expr

Struct Expr 

Source
pub struct Expr<'a> {
    pub root: Node,
    pub context: Option<&'a Context<'a>>,
}
Expand description

A fully parsed and bound schema expression.

It may be evaluated with Eval to generate passwords from its domain.

Fields§

§root: Node§context: Option<&'a Context<'a>>

Implementations§

Source§

impl Expr<'_>

Source

pub fn parse(input: &str) -> Result<Self, Error>

Expressions can be parsed from UTF-8 strings.

The following syntax is supported:

§String literals

Any literal string that does not otherwise consist of syntax characters stands for itself. A schema consisting of a literal string generates itself as the single password. Other characters may be escaped with '\\'; aside from newline, carriage return, and tab, any non-alphanumeric character stands for itself as a literal value when preceded by a backslash.

assert_eq!(Node::Literal("test".into()), "test".parse().unwrap());
assert_eq!(Node::Literal("(escape){}[]".into()), r#"\(escape\)\{\}\[\]"#.parse().unwrap());

Arbitrary Unicode characters may also be insterted as \uXXXX, or hex sequences (so long as they encode valid ASCII or UTF-8 byte sequences) as \xXX.

§Character classes

The special character classes \w and \d stand for word (alphanumeric plus underscore) and digit characters respectively. They may show up anywhere in an expression and stand for a single character in their range.

Square bracket character classes are also supported, including the following POSIX character classes:

  • [:lower:] - lowercase ASCII letters
  • [:upper:] - uppercase ASCII letters
  • [:alpha:] - upper or lowercase ASCII letters
  • [:digit:] - decimal digits
  • [:xdigit:] - lowercase hexadecimal digits
  • [:punct:] - ASCII punctuation, aka special characters
  • [:print:] - printable ASCII characters

Single characters ([a]) and unicode character ranges ([a-z]) are also supported.

Any of these ranges may be combined within square brackets; [[:upper:][a-z]\d] corresponds to uppercase ASCII, lowercase ASCII, and decimal digits.

assert_eq!("[a-z]".parse::<Node>().unwrap(), "[[:lower:]]".parse().unwrap());
assert_eq!("[A-Za-z0-9_]".parse::<Node>().unwrap(), "\\w".parse().unwrap());
§Lists

A sequence of nodes is represented by its concatenation. A nested list may be created using parentheses (()). This is of limited utility since the language does not support choices, but does allow e.g. setting a count on a sequence, like: ([[:lower:]][[:digit:]][[:lower:]]){3}.

assert_eq!(
    NonZero::new(U256::from_u64((26u64*10*26).pow(3))).unwrap(),
    Expr::new("([[:lower:]][[:digit:]][[:lower:]]){3}".parse().unwrap()).size()
);
§Counts

As alluded to, expressions may be repeated for specified counts. The syntax is expr{min,max}. If max is omitted, i.e. expr{min}, then max == min. If min is omitted, i.e. expr{,max}, then min == 0.

NB. In the current revision of the schema language, a count after a literal applies to the whole string, not just the last character; so ab{2} is equivalent to (ab){2}, not a(b){2}:

assert_eq!("(ab){2}".parse::<Node>().unwrap(), "ab{2}".parse().unwrap());
§Generators

Arbitrary library-suppliable generators may be called. The library includes two: word to produce a single word, and words to produce a sequence of words. Generators are surrounded by curly braces and must start with a lowercase ASCII letter, e.g. {word}. (This rule is what differentiates them from counts, which must start with an ASCII digit.)

Generators may take arguments. The first non–lowercase-ASCII character in a generator expression is taken as an argument separator, so e.g. {words:2:U} calls generator words with arguments "2" and "U".

§Reserved syntax

The | character may be used inside of generators as an argument separator, like {word|U}, but may not be used unescaped anywhere else in an expression. This syntax is reserved for possible future expansion.

§Errors

It is an error to write a character class with the higher character before the lower character, e.g. [b-a].

assert!("[b-a]".parse::<Node>().is_err());

Partial remainders, e.g. in the case of unbalanced delimiters, yield an error. (These can, and should, simply be backslash-escaped.)

assert!("abcd}".parse::<Node>().is_err());
assert!("abcd\\}".parse::<Node>().is_ok());

At present, hex sequences that do not encode valid UTF-8 encoded text are an error.

The syntax [:word:] (and [:Word:]) used to be the way to generate a word from a dictionary in onepass v2. In the current syntax, these would both parse to degenerate character classes, e.g. [:dorw]. Since this is virtually never intended, those specific strings are presently a parse error.

§Context

This function returns an expression against the default context. Self::parse_with_context may be used to parse an expression against a custom context.

Source§

impl<'a> Expr<'a>

Source

pub fn parse_with_context( input: &str, context: &'a Context<'a>, ) -> Result<Self, Error>

parse an expression with the given Context.

Source§

impl Expr<'_>

Source

pub fn write_repr<W>(&self, w: &mut W) -> Result
where W: Write,

Write the canonical serialization of this expression. This function implements this type’s fmt::Display.

Source§

impl Expr<'_>

Source

pub fn new(root: Node) -> Self

Construct a new expression with the default generator context.

Source§

impl<'a> Expr<'a>

Source

pub fn with_context(root: Node, context: &'a Context<'a>) -> Self

Source

pub fn get_context(&self) -> &Context<'a>

Trait Implementations§

Source§

impl<'a> Debug for Expr<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Expr<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eval for Expr<'_>

Source§

fn size(&self) -> NonZero<U256>

Returns the total number of passwords generated by this type, or some reasonable approximation thereof (e.g. a type that constructs and samples its own RNG might return the size of the RNG state here), but caution should be used when deviating too far from the literal count/enumeration paradigm, as this may cause entropy estimates to be misleading.
Source§

fn write_to( &self, w: &mut dyn Write, index: &mut dyn ExposeSecretMut<U256>, ) -> Result<()>

Write the string at the given index to the given Write instance. Typically the string at index 0 will be the lowest or lexicographically first password, and the string at self.size() - 1 will be the highest or lexicographically last password, but this is not required.

Auto Trait Implementations§

§

impl<'a> Freeze for Expr<'a>

§

impl<'a> !RefUnwindSafe for Expr<'a>

§

impl<'a> Send for Expr<'a>

§

impl<'a> Sync for Expr<'a>

§

impl<'a> Unpin for Expr<'a>

§

impl<'a> UnsafeUnpin for Expr<'a>

§

impl<'a> !UnwindSafe for Expr<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.