Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/sfv/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 5 kB image not shown  

Quelle  key.rs

  Sprache: Rust
 

use std::{borrow::Borrow, fmt};

use crate::{
    error::{Error, NonEmptyStringError},
    utils,
};

/// An owned structured field value [key].
///
/// Keys must match the following regular expression:
///
/// ```re
/// ^[A-Za-z*][A-Za-z*0-9!#$%&'+\-.^_`|~]*$
/// ```
///
/// [key]: <https://httpwg.org/specs/rfc9651.html#key>
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Key(String);

/// A borrowed structured field value [key].
///
/// Keys must match the following regular expression:
///
/// ```re
/// ^[A-Za-z*][A-Za-z*0-9!#$%&'+\-.^_`|~]*$
/// ```
///
/// This type is to [`Key`] as [`str`] is to [`String`].
///
/// [key]: <https://httpwg.org/specs/rfc9651.html#key>
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, ref_cast::RefCastCustom)]
#[repr(transparent)]
pub struct KeyRef(str);

const fn validate(v: &[u8]) -> Result<(), NonEmptyStringError> {
    if v.is_empty() {
        return Err(NonEmptyStringError::empty());
    }

    if !utils::is_allowed_start_key_char(v[0]) {
        return Err(NonEmptyStringError::invalid_character(0));
    }

    let mut index = 1;

    while index < v.len() {
        if !utils::is_allowed_inner_key_char(v[index]) {
            return Err(NonEmptyStringError::invalid_character(index));
        }
        index += 1;
    }

    Ok(())
}

impl KeyRef {
    #[ref_cast::ref_cast_custom]
    const fn cast(v: &str) -> &Self;

    /// Creates a `&KeyRef` from a `&str`.
    ///
    /// # Errors
    /// If the input string validation fails.
    #[allow(clippy::should_implement_trait)]
    pub fn from_str(v: &str) -> Result<&Self, Error> {
        validate(v.as_bytes())?;
        Ok(Self::cast(v))
    }

    // Like `from_str`, but assumes that the contents of the string have already
    // been validated as a key.
    pub(cratefn from_validated_str(v: &str) -> &Self {
        debug_assert!(validate(v.as_bytes()).is_ok());
        Self::cast(v)
    }

    /// Creates a `&KeyRef`, panicking if the value is invalid.
    ///
    /// This method is intended to be called from `const` contexts in which the
    /// value is known to be valid. Use [`KeyRef::from_str`] for non-panicking
    /// conversions.
    ///
    /// # Errors
    /// If the input string validation fails.
    #[must_use]
    pub const fn constant(v: &str) -> &Self {
        match validate(v.as_bytes()) {
            Ok(()) => Self::cast(v),
            Err(err) => panic!("{}", err.msg()),
        }
    }

    /// Returns the key as a `&str`.
    #[must_use]
    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl ToOwned for KeyRef {
    type Owned = Key;

    fn to_owned(&self) -> Key {
        Key(self.0.to_owned())
    }

    fn clone_into(&self, target: &mut Key) {
        self.0.clone_into(&mut target.0);
    }
}

impl Borrow<KeyRef> for Key {
    fn borrow(&self) -> &KeyRef {
        self
    }
}

impl std::ops::Deref for Key {
    type Target = KeyRef;

    fn deref(&self) -> &KeyRef {
        KeyRef::cast(&self.0)
    }
}

impl From<Key> for String {
    fn from(v: Key) -> String {
        v.0
    }
}

impl TryFrom<String> for Key {
    type Error = Error;

    fn try_from(v: String) -> Result<Key, Error> {
        validate(v.as_bytes())?;
        Ok(Key(v))
    }
}

impl Key {
    /// Creates a `Key` from a `String`.
    ///
    /// Returns the original value if the conversion failed.
    ///
    /// # Errors
    /// If the input string validation fails.
    pub fn from_string(v: String) -> Result<Self, (Error, String)> {
        match validate(v.as_bytes()) {
            Ok(()) => Ok(Self(v)),
            Err(err) => Err((err.into(), v)),
        }
    }
}

/// Creates a `&KeyRef`, panicking if the value is invalid.
///
/// This is a convenience free function for [`KeyRef::constant`].
///
/// This method is intended to be called from `const` contexts in which the
/// value is known to be valid. Use [`KeyRef::from_str`] for non-panicking
/// conversions.
#[must_use]
pub const fn key_ref(v: &str) -> &KeyRef {
    KeyRef::constant(v)
}

impl fmt::Display for KeyRef {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

impl fmt::Display for Key {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        <KeyRef as fmt::Display>::fmt(self, f)
    }
}

macro_rules! impl_eq {
    ($a: ty, $b: ty) => {
        impl PartialEq<$a> for $b {
            fn eq(&self, other: &$a) -> bool {
                <KeyRef as PartialEq>::eq(self, other)
            }
        }
        impl PartialEq<$b> for $a {
            fn eq(&self, other: &$b) -> bool {
                <KeyRef as PartialEq>::eq(self, other)
            }
        }
    };
}

impl_eq!(Key, KeyRef);
impl_eq!(Key, &KeyRef);

impl<'a> TryFrom<&'a str> for &'a KeyRef {
    type Error = Error;

    fn try_from(v: &'a str) -> Result<&'a KeyRef, Error> {
        KeyRef::from_str(v)
    }
}

impl Borrow<str> for Key {
    fn borrow(&self) -> &str {
        self.as_str()
    }
}

impl Borrow<str> for KeyRef {
    fn borrow(&self) -> &str {
        self.as_str()
    }
}

impl AsRef<KeyRef> for Key {
    fn as_ref(&self) -> &KeyRef {
        self
    }
}

impl AsRef<KeyRef> for KeyRef {
    fn as_ref(&self) -> &KeyRef {
        self
    }
}

#[cfg(feature = "arbitrary")]
impl<'a> arbitrary::Arbitrary<'a> for &'a KeyRef {
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
        KeyRef::from_str(<&str>::arbitrary(u)?).map_err(|_| arbitrary::Error::IncorrectFormat)
    }

    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
        (1, None)
    }
}

#[cfg(feature = "arbitrary")]
impl<'a> arbitrary::Arbitrary<'a> for Key {
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
        <&KeyRef>::arbitrary(u).map(ToOwned::to_owned)
    }

    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
        (1, None)
    }
}

Messung V0.5 in Prozent
C=81 H=99 G=90

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.