Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facilities for writing custom Patterns #39

Open
arlyon opened this issue May 18, 2023 · 0 comments
Open

Facilities for writing custom Patterns #39

arlyon opened this issue May 18, 2023 · 0 comments

Comments

@arlyon
Copy link
Contributor

arlyon commented May 18, 2023

Hi! Great library!

I would like to be able to write custom combinators such as InclusiveEmptyAny which matches any path in the event that the list of globs is empty. I tried implementing Pattern and Compose myself to do so but it seems like I need to implement From<Checked> to do so, which is private. The types that the library uses to do so are private also, so it seems that this is not possible as-is.

Similarly, it is impossible to implement Pattern::matched correctly since MatchedText and friends are currently private also.

Any pointers?

//! A simple `wax` combinator that unconditionally matches if the set of globs
//! is empty.

use std::convert::Infallible;

use wax::{Any, BuildError, CandidatePath, Compose, MatchedText, Pattern, Variance};

pub struct InclusiveEmptyAny<'a>(Option<Any<'a>>);

impl<'a> InclusiveEmptyAny<'a> {
    pub fn new<I>(patterns: I) -> Result<Self, BuildError>
    where
        I: IntoIterator,
        I::Item: Compose<'a>,
    {
        let iter = patterns.into_iter().collect::<Vec<_>>();
        if iter.len() == 0 {
            Ok(Self(None))
        } else {
            Ok(Self(Some(wax::any(iter)?)))
        }
    }
}

impl<'t> Compose<'t> for InclusiveEmptyAny<'t> {
    type Tokens = (); // what should this be?
    type Error = Infallible;
}

impl<'t> Pattern<'t> for InclusiveEmptyAny<'t> {
    fn is_match<'p>(&self, path: impl Into<CandidatePath<'p>>) -> bool {
        match self.0 {
            Some(ref any) => any.is_match(path),
            None => true,
        }
    }

    fn matched<'p>(&self, path: &'p CandidatePath<'_>) -> Option<MatchedText<'p>> {
        match self.0 {
            Some(ref any) => any.matched(path),
            None => Some(path.into()), // is this ok?
        }
    }

    fn variance(&self) -> Variance {
        match self.0 {
            Some(ref any) => any.variance(),
            None => Variance::Variant,
        }
    }

    fn is_exhaustive(&self) -> bool {
        match self.0 {
            Some(ref any) => any.is_exhaustive(),
            None => true,
        }
    }
}
error[E0277]: the trait bound `wax::rule::Checked<()>: From<InclusiveEmptyAny<'t>>` is not satisfied
   --> crates/globwalk/src/empty_glob.rs:27:18
    |
27  |     type Error = Infallible;
    |                  ^^^^^^^^^^ the trait `From<InclusiveEmptyAny<'t>>` is not implemented for `wax::rule::Checked<()>`
    |
    = help: the following other types implement trait `From<T>`:
              <wax::rule::Checked<wax::token::Token<'t, ()>> as From<wax::Any<'t>>>
              <wax::rule::Checked<wax::token::Tokenized<'t>> as From<Glob<'t>>>
    = note: required for `InclusiveEmptyAny<'t>` to implement `Into<wax::rule::Checked<()>>`
    = note: required for `wax::rule::Checked<()>` to implement `TryFrom<InclusiveEmptyAny<'t>>`
note: required by a bound in `Compose`
   --> /Users/arlyon/Programming/wax/src/lib.rs:314:36
    |
314 |     TryInto<Checked<Self::Tokens>, Error = <Self as Compose<'t>>::Error>
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Compose`

error[E0277]: the trait bound `wax::rule::Checked<()>: From<InclusiveEmptyAny<'t>>` is not satisfied
   --> crates/globwalk/src/empty_glob.rs:30:10
    |
30  | impl<'t> Pattern<'t> for InclusiveEmptyAny<'t> {
    |          ^^^^^^^^^^^ the trait `From<InclusiveEmptyAny<'t>>` is not implemented for `wax::rule::Checked<()>`
    |
    = help: the following other types implement trait `From<T>`:
              <wax::rule::Checked<wax::token::Token<'t, ()>> as From<wax::Any<'t>>>
              <wax::rule::Checked<wax::token::Tokenized<'t>> as From<Glob<'t>>>
    = note: required for `InclusiveEmptyAny<'t>` to implement `Into<wax::rule::Checked<()>>`
    = note: required for `wax::rule::Checked<()>` to implement `TryFrom<InclusiveEmptyAny<'t>>`
    = note: required for `InclusiveEmptyAny<'t>` to implement `Compose<'t>`
note: required by a bound in `wax::Pattern`
   --> /Users/arlyon/Programming/wax/src/lib.rs:276:24
    |
276 | pub trait Pattern<'t>: Compose<'t, Error = Infallible> {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Pattern`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant