errorstash 0.2.0

A library for collecting multiple related errors, and reporting them together
Documentation

errorstash

A library for collecting multiple related errors, and reporting them together.

use std::collections::HashSet;
use url::Url;
use thiserror::Error;
use errorstash::{ErrorStash, BoxedStash, BoxedErrors, StashableResult};

#[derive(Error, Debug)]
#[error("Domain '{0}' is not trusted")]
struct InvalidDomainError(String);

#[derive(Debug, PartialEq, Eq)]
struct TrustedUrl(String);

#[derive(Debug)]
struct UrlValidator(HashSet<String>);

impl UrlValidator {
    fn new(trusted_domains: Vec<String>) -> Self {
        Self(trusted_domains.into_iter().collect())
    }

    /// Validates that the given URL complies with our requirements, and if
    /// so, returns it as a `TrustedUrl`.
    fn validate_url(&self, url: &str) -> Result<TrustedUrl, BoxedErrors> {
        let mut stash = BoxedStash::with_summary("Invalid URL:");
        let parsed = Url::parse(url)
            .or_fail(&mut stash)?;

        stash
            .check(parsed.scheme() == "https", "URL must use https schema")
            .check(parsed.port().is_none(), "URL must not specify a port");
        let raw_domain = parsed.host_str().unwrap_or_default();
        if raw_domain.is_empty() {
            stash.push("URL must have a domain");
        } else if !self.0.contains(raw_domain) {
            let e = InvalidDomainError(raw_domain.into());
            stash.push(e);
        }
        stash.fail_unless_empty()?;

        let as_safe = TrustedUrl(url.into());
        Ok(as_safe)
    }
}

Crates.io Docs.rs CI

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

See CONTRIBUTING.md.