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

match enum struct variant defect? #103

Open
LittleEntity opened this issue Jun 4, 2021 · 2 comments
Open

match enum struct variant defect? #103

LittleEntity opened this issue Jun 4, 2021 · 2 comments

Comments

@LittleEntity
Copy link

LittleEntity commented Jun 4, 2021

I try to match the following enum with internal struct variants

pub enum ValidationError {
    LengthOutOfBounds {
        min: usize,
        max: usize,
    },
    InvalidName {
        invalid_chars: Vec<char>,
    },
    UniqueConstraintViolation,
}

with

@use crate::ValidationError::{self, *};

@(error: &ValidationError)

@match error {
    UniqueConstraintViolation => {
        This name is taken.
    }
    LengthOutOfBounds { min, max } => {
        This field must contain at min @min and at max @max characters.
    }
    InvalidName { invalid_chars } => {
        @format!("The name must not contain any of the following characters: {:?}", invalid_chars)
    }
}

The error message is:

warning: Template parse error in "template_src/validation_error_display_part.rs.html":
warning:    5:@match error {
warning:      ^ Error in expression starting here:
warning:    5:@match error {
warning:             ^ Error in match expression:
warning:    8:    }
warning:           ^ Error in match arm starting here:

this works:

@use crate::ValidationError::{self, *};

@(error: &ValidationError)

@match error {
    UniqueConstraintViolation(value) => {
        This name is taken.
    }
    _ => {
        other error
    }
}

In rust this works:

impl<'s> std::fmt::Display for ValidationError<'s> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        use ValidationError::*;
        match self {
            LengthOutOfBounds { min, max } => {
                write!(
                    f,
                    "This field must contain at min {} and at max {} characters.",
                    min, max
                )
            }
            InvalidName {
                invalid_chars,
            } => {
                write!(
                    f,
                    "The name must not contain any of the following characters: {:?}",
                    invalid_chars
                )
            }
            UniqueConstraintViolation => {
                write!(f, "This name is taken.")
            }
        }
    }
}

Am I doing something wrong? Is this a defect of the library?

I enjoy using ructe 🦀 thankyou for sharing 🙏

@LittleEntity LittleEntity changed the title match struct broken? match enum struct variant defect? Jun 4, 2021
@kaj
Copy link
Owner

kaj commented Jun 4, 2021

Yes, this seems like a defect in ructe. I'll try to fix it.

@LittleEntity
Copy link
Author

LittleEntity commented Jun 4, 2021

I guess it can be fixed here:

(i, Some(b"match")) => context(
"Error in match expression:",
map(
tuple((
delimited(spacelike, expression, spacelike),
preceded(
char('{'),
map(
many_till(
context(
"Error in match arm starting here:",
pair(
delimited(
spacelike,
map(expression, String::from),
spacelike,
),
preceded(
terminated(tag("=>"), spacelike),
template_block,
),
),
),
preceded(spacelike, char('}')),
),
|(arms, _end)| arms,
),
),
)),
|(expr, arms)| TemplateExpression::MatchBlock {
expr: expr.to_string(),
arms,
},
),
)(i),

Unfortunatly I only have some experience with https://pest.rs/ . Nom seems to be a fine parsing library too. Maybe I will find some spare time this weekend to look into https://lib.rs/crates/nom. Maybe I can contribute in the future ^^.

Please take note there is more to the match syntax to explore: https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html

There are many cases I didn't know of before. For example the @ binding. It seems to be a huge task to parse every possible match syntax pattern correctly. I personally use this pattern as well:

enum Variation {
    Structure {
        id: usize,
        name: String,
        not_used: i32,
    },
    SimpleVariant,
}

fn main() {
    let variation = Variation::Structure {
        id: 42,
        name: "an example for the great ructe lib 🦀".into(),
        not_used: -123,
    };
    
    match variation {
        Variation::Structure {
            id,
            name: the_name, 
            ..
        } => {
            println!(r#"Object with ID {} has the name "{}""#, id, the_name);
        }
        Variation::SimpleVariant => {
            println!("This is just a simple variant match");
        }
    }
}

Please consider documenting which patterns are explicitly implemented and tested. If the mentioned enum/struct patterns work, that would be great. If you cannot fix it, because of lack of time or whatever reason, I will try to make a good work around =) thankyou 🙏

Are you looking for help with this library of yours? If so I will check if I can take off some spare time to contribute to this lib.

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

2 participants