Skip to content

Commit

Permalink
Update documentation for Program and query types.
Browse files Browse the repository at this point in the history
  • Loading branch information
olson-sean-k committed Mar 18, 2024
1 parent 08cab4e commit 6280daf
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 123 deletions.
81 changes: 64 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,33 @@ impl StrExt for str {
/// A representation of a glob expression.
///
/// This trait is implemented by types that can be converted into a [`Program`], such as `str`
/// slices and, of course, [`Program`] types like [`Glob`].
/// slices and compiled [`Program`] types like [`Glob`]. APIs that accept patterns typically do so
/// via this trait.
///
/// [`Result`] types also implement this trait when the okay type is a [`Program`] and the error
/// type is [`BuildError`]. This means that APIs that accept a `Pattern` can also accept the result
/// of constructing a [`Program`] without the need to explicitly inspect the inner result first.
/// # Examples
///
/// [`Result`] types also implement this trait when the success type is a [`Program`] and the error
/// type is [`BuildError`]. This means that APIs that accept a `Pattern` can also accept the
/// intermediate result of constructing a [`Program`] without the need to explicitly inspect the
/// inner result first (error handling can be deferred).
///
/// ```rust
/// use wax::{Glob, Program};
///
/// # fn fallible() -> Result<(), wax::BuildError> {
/// // The inner results of `any` are not checked via `?` and can be passed directly to the
/// // outermost `any` call. This is true of all APIs that accept `Pattern`.
/// #[rustfmt::skip]
/// let any = wax::any([
/// wax::any([Glob::new("**/*.txt")]),
/// wax::any([
/// "**/*.pdf",
/// "**/*.tex",
/// ]),
/// ])?; // Defer error handling until the here.
/// # Ok(())
/// # }
/// ```
///
/// [`BuildError`]: crate::BuildError
/// [`Glob`]: crate::Glob
Expand Down Expand Up @@ -150,44 +172,69 @@ impl<'t> Pattern<'t> for &'t str {

/// A compiled [`Pattern`] that can be inspected and matched against paths.
///
/// Matching is a logical operation and does **not** interact with a file system. To handle path
/// operations, use [`Path`] and/or [`PathBuf`] and their associated functions. See
/// [`Glob::partition`] and `Glob::walk` for more about globs and path operations.
///
/// [`Glob::partition`]: crate::Glob::partition
/// [`Path`]: std::path::Path
/// [`PathBuf`]: std::path::PathBuf
/// [`Pattern`]: crate::Pattern
pub trait Program<'t>: Pattern<'t, Error = Infallible> {
/// Returns `true` if a path matches the pattern.
/// Returns `true` if the [candidate path][`CandidatePath`] matches the pattern.
///
/// The given path must be convertible into a [`CandidatePath`].
/// This is a logical operation and does **not** interact with the file system.
///
/// [`CandidatePath`]: crate::CandidatePath
fn is_match<'p>(&self, path: impl Into<CandidatePath<'p>>) -> bool;

/// Gets [matched text][`MatchedText`] in a [`CandidatePath`].
/// Gets the [matched text][`MatchedText`] in a [`CandidatePath`], if any.
///
/// Returns `None` if the [`CandidatePath`] does not match the pattern.
/// Returns `None` if the [`CandidatePath`] does not match the pattern. This is a logical
/// operation and does **not** interact with the file system.
///
/// [`CandidatePath`]: crate::CandidatePath
/// [`MatchedText`]: crate::MatchedText
fn matched<'p>(&self, path: &'p CandidatePath<'_>) -> Option<MatchedText<'p>>;

/// Gets the depth variance of the pattern.
fn depth(&self) -> DepthVariance;

/// Gets the text variance of the pattern.
///
/// # Examples
///
/// Text variance can be used to determine if a pattern can be trivially represented by an
/// equivalent path using platform file system APIs.
///
/// ```rust
/// use std::path::Path;
/// use wax::{Glob, Program};
///
/// let glob = Glob::new("/home/user").unwrap();
/// let text = glob.text();
/// let path = text.as_path();
///
/// assert_eq!(path, Some(Path::new("/home/user")));
/// ```
fn text(&self) -> TextVariance<'t>;

/// Returns `true` if the glob has a root.
/// Describes when the pattern matches candidate paths with a root.
///
/// A glob expression that begins with a separator `/` has a root, but less trivial patterns
/// like `/**` and `</root:1,>` can also root an expression. Some `Program` types may have
/// indeterminate roots and may match both candidate paths with and without a root. In this
/// case, this functions returns [`Sometimes`] (indeterminate).
///
/// As with Unix paths, a glob expression has a root if it begins with a separator `/`.
/// Patterns other than separators may also root an expression, such as `/**` or `</root:1,>`.
/// [`Sometimes`]: crate::query::When::Sometimes
fn has_root(&self) -> When;

/// Returns `true` if the pattern is exhaustive.
///
/// A glob expression is exhaustive if its terminating component matches any and all sub-trees,
/// such as in the expressions `/home/**` and `local/<<?>/>*`.
/// A glob expression is exhaustive if, given a matched candidate path, it necessarily matches
/// any and all sub-trees of that path. For example, glob expressions that end with a tree
/// wildcard like `.local/**` are exhaustive, but so are less trivial expressions like `<<?>/>`
/// and `<doc/<*/:3,>>`. This can be an important property when determining what directory
/// trees to read or which files and directories to select with a pattern.
///
/// Note that this applies to the **pattern** and **not** to a particular match. It is possible
/// for a particular match against a **non**exhaustive pattern to be exhaustive.
fn is_exhaustive(&self) -> bool;
}

Expand Down
Loading

0 comments on commit 6280daf

Please sign in to comment.