Skip to content

Support for returning parsed data from InputValidator #104

@tyilo

Description

@tyilo

I propose that Input and InputValidator should be changed to:

pub struct Input<'a, T = String> {
    ...
    pub validation: Box<dyn InputValidator<Output = T>>,
    ...
}

impl<'a, T> Input<'a, T> {
    pub fn run(mut self) -> io::Result<T>;
}

pub trait InputValidator {
    type Output;

    fn check(&self, input: &str) -> Result<Self::Output, String>;
}

Currently you might need to both parse the provided string in the validator and after Input::run returns, which this could prevent.

Example with current demand:

use demand::{Input, InputValidator};

struct Parser;

fn parse(s: &str) -> Result<serde_json::Value, String> {
    let value: serde_json::Value = serde_json::from_str(s).map_err(|e| e.to_string())?;
    Ok(value)
}

impl InputValidator for Parser {
    fn check(&self, input: &str) -> Result<(), String> {
        parse(input).map(|_| ())
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json = Input::new("Enter JSON:").validator(Parser).run()?;

    let value = parse(&json).unwrap();
    println!("{value:#?}");

    Ok(())
}

With new proposed demand:

use demand::{Input, InputValidator};

struct Parser;

impl InputValidator for Parser {
    type Output = serde_json::Value;

    fn check(&self, input: &str) -> Result<Self::Output, String> {
        serde_json::from_str(input).map_err(|e| e.to_string())
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json = Input::new("Enter JSON:").validator(Parser).run()?;

    println!("{value:#?}");

    Ok(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions