Trait PurlShape

Source
pub trait PurlShape {
    type Error: From<ParseError>;

    // Required methods
    fn package_type(&self) -> Cow<'_, str>;
    fn finish(&mut self, parts: &mut PurlParts) -> Result<(), Self::Error>;
}
Expand description

A type that provides package-type-specific behavior.

If it supports your requirements, you can use or extend PackageType. (see also Purl)

If you don’t care about package-type-specific behavior, you can use String, Cow<str>, or SmallString.

§Example

use std::borrow::Cow;
use std::str::FromStr;

use purl::{GenericPurl, GenericPurlBuilder, ParseError, PurlParts, PurlShape};

enum MyPackageType {
    Custom,
}

#[derive(Debug, thiserror::Error)]
enum MyError {
    #[error("Parse error: {0}")]
    Parse(#[from] ParseError),
    #[error("Unsupported package type")]
    UnsupportedType,
    #[error("Required repository_url qualifier was not found")]
    MissingRepositoryUrl,
}

impl FromStr for MyPackageType {
    type Err = MyError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("custom") {
            Ok(MyPackageType::Custom)
        } else {
            Err(MyError::UnsupportedType)
        }
    }
}

impl PurlShape for MyPackageType {
    type Error = MyError;

    fn package_type(&self) -> Cow<str> {
        match self {
            // Always use lower case types here.
            // Upper case characters are not invalid, but the canonical type name is always
            // lower case.
            MyPackageType::Custom => Cow::Borrowed("custom"),
        }
    }

    fn finish(&mut self, parts: &mut PurlParts) -> Result<(), Self::Error> {
        match self {
            MyPackageType::Custom => {
                // pkg:custom names are always lower case.
                parts.name = parts.name.to_lowercase().into();
                // pkg:custom requires a repository_url.
                if !parts.qualifiers.contains_key("repository_url") {
                    return Err(MyError::MissingRepositoryUrl);
                }
            },
        }
        Ok(())
    }
}

type Purl = GenericPurl<MyPackageType>;
type PurlBuilder = GenericPurlBuilder<MyPackageType>;

assert!(matches!(
    Purl::from_str("pkg:custom/Example?repository_url=https://example.com/")
        .map(|p| p.to_string())
        .as_deref(),
    Ok("pkg:custom/example?repository_url=https://example.com/"),
));
assert!(matches!(Purl::from_str("pkg:custom/Example"), Err(MyError::MissingRepositoryUrl),));

Required Associated Types§

Source

type Error: From<ParseError>

The type of error returned by this package type.

Required Methods§

Source

fn package_type(&self) -> Cow<'_, str>

Get the string representation of this PurlShape.

The returned value should be a lower case string. If the returned value contains invalid characters, Display and to_string will panic.

Source

fn finish(&mut self, parts: &mut PurlParts) -> Result<(), Self::Error>

Preview and potentially modify the parts that make up a PURL.

This is called when a GenericPurl is being created. It gives the PurlShape implementation a chance to perform validation and normalization.

Implementations on Foreign Types§

Source§

impl PurlShape for Cow<'_, str>

A generic PurlShape that can support any package type but does not provide any type-specific functionality.

Without type-specific functionality, it’s possible to create PURLs that have incorrect capitalization or are missing a required namespace or required qualifiers.

Source§

type Error = ParseError

Source§

fn package_type(&self) -> Cow<'_, str>

Source§

fn finish(&mut self, _parts: &mut PurlParts) -> Result<(), Self::Error>

Source§

impl PurlShape for String

A generic PurlShape that can support any package type but does not provide any type-specific functionality.

Without type-specific functionality, it’s possible to create PURLs that have incorrect capitalization or are missing a required namespace or required qualifiers.

Source§

type Error = ParseError

Source§

fn package_type(&self) -> Cow<'_, str>

Source§

fn finish(&mut self, _parts: &mut PurlParts) -> Result<(), Self::Error>

Source§

impl<M> PurlShape for SmartString<M>
where M: SmartStringMode,

Available on crate feature smartstring only.

A generic PurlShape that can support any package type but does not provide any type-specific functionality.

Without type-specific functionality, it’s possible to create PURLs that have incorrect capitalization or are missing a required namespace or required qualifiers.

Source§

type Error = ParseError

Source§

fn package_type(&self) -> Cow<'_, str>

Source§

fn finish(&mut self, _parts: &mut PurlParts) -> Result<(), Self::Error>

Implementors§

Source§

impl PurlShape for PackageType

Available on crate feature package-type only.