1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::{
    query_or_fragment::{validate, QueryOrFragment},
    validation::InvalidComponent,
};
use boar_::BoasStr;
use std::{borrow::Borrow, error::Error, fmt};

#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub struct Fragment<'a>(QueryOrFragment<'a>);

impl<'a> Fragment<'a> {
    #[inline]
    pub fn new() -> Self {
        Self::default()
    }

    fn internal_try_from(string: BoasStr<'a>) -> Result<Self, InvalidFragment> {
        Ok(Self(
            QueryOrFragment::internal_try_from(string).map_err(InvalidFragment)?,
        ))
    }

    #[inline]
    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }

    pub fn into_static(self) -> Fragment<'static> {
        Fragment(self.0.into_static())
    }

    pub fn to_borrowed(&self) -> Fragment {
        Fragment(self.0.to_borrowed())
    }
}

impl Fragment<'static> {
    #[inline]
    pub fn ensure_static(&mut self) {
        self.0.ensure_static()
    }

    #[inline]
    pub fn into_ensured_static(mut self) -> Self {
        self.ensure_static();
        self
    }

    pub fn try_from_static(string: &'static str) -> Result<Self, InvalidFragment> {
        Self::internal_try_from(BoasStr::Static(string))
    }

    #[track_caller]
    pub const fn from_static(string: &'static str) -> Self {
        match validate(string.as_bytes()) {
            Ok(()) => Self(QueryOrFragment(BoasStr::Static(string))),
            Err(_e) => panic!("invalid static Fragment"),
        }
    }
}

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

    fn try_from(string: &'a str) -> Result<Self, InvalidFragment> {
        Self::internal_try_from(BoasStr::Borrowed(string))
    }
}

impl<'a> TryFrom<String> for Fragment<'a> {
    type Error = InvalidFragment;

    fn try_from(string: String) -> Result<Self, InvalidFragment> {
        Self::internal_try_from(BoasStr::Owned(string))
    }
}

#[cfg(feature = "boar")]
impl<'a> TryFrom<BoasStr<'a>> for Fragment<'a> {
    type Error = InvalidFragment;

    fn try_from(string: BoasStr<'a>) -> Result<Self, InvalidFragment> {
        Self::internal_try_from(string)
    }
}

impl AsRef<str> for Fragment<'_> {
    fn as_ref(&self) -> &str {
        self.0.as_ref()
    }
}

impl Borrow<str> for Fragment<'_> {
    fn borrow(&self) -> &str {
        self.0.borrow()
    }
}

impl PartialEq<str> for Fragment<'_> {
    fn eq(&self, other: &str) -> bool {
        self.0 == other
    }
}

impl PartialEq<&'_ str> for Fragment<'_> {
    fn eq(&self, &other: &&str) -> bool {
        self == other
    }
}

#[derive(Debug, Clone)]
pub struct InvalidFragment(InvalidComponent);

impl fmt::Display for InvalidFragment {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "invalid fragment: {}", self.0)
    }
}

impl Error for InvalidFragment {}