Sebastian Thielj fmtc3c65041 year agoHistory
128 lines · 3.8 KB · Rust
RawDownload
use bstr::{BStr, BString, ByteSlice}; use crate::{State, StateRef}; /// A container to encapsulate a tightly packed and typically unallocated byte value that isn't necessarily UTF8 encoded.#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]// TODO: This should be some sort of 'smallbstring' - but can't use `kstring` here due to UTF8 requirement. 5% performance boost possible.//       What's really needed here is a representation that displays as string when serialized which helps with JSON.//       Maybe `smallvec` with display and serialization wrapper would do the trick?pub struct Value(BString); /// A reference container to encapsulate a tightly packed and typically unallocated byte value that isn't necessarily UTF8 encoded.#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]pub struct ValueRef<'a>(#[cfg_attr(feature = "serde", serde(borrow))] &'a [u8]); /// Lifecycleimpl<'a> ValueRef<'a> {    /// Keep `input` as our value.    pub fn from_bytes(input: &'a [u8]) -> Self {        Self(input)    }} /// Access and conversionsimpl<'a> ValueRef<'a> {    /// Access this value as byte string.    pub fn as_bstr(&self) -> &'a BStr {        self.0.as_bytes().as_bstr()    }     /// Convert this instance into its owned form.    pub fn to_owned(self) -> Value {        self.into()    }} impl<'a> From<&'a str> for ValueRef<'a> {    fn from(v: &'a str) -> Self {        ValueRef(v.as_bytes())    }} impl<'a> From<ValueRef<'a>> for Value {    fn from(v: ValueRef<'a>) -> Self {        Value(v.0.into())    }} impl From<&str> for Value {    fn from(v: &str) -> Self {        Value(v.as_bytes().into())    }} /// Accessimpl Value {    /// Return ourselves as reference.    pub fn as_ref(&self) -> ValueRef<'_> {        ValueRef(self.0.as_ref())    }} /// Accessimpl StateRef<'_> {    /// Return `true` if the associated attribute was set to be unspecified using the `!attr` prefix or it wasn't mentioned.    pub fn is_unspecified(&self) -> bool {        matches!(self, StateRef::Unspecified)    }     /// Return `true` if the associated attribute was set with `attr`. Note that this will also be `true` if a value is assigned.    pub fn is_set(&self) -> bool {        matches!(self, StateRef::Set | StateRef::Value(_))    }     /// Return `true` if the associated attribute was set with `-attr` to specifically remove it.    pub fn is_unset(&self) -> bool {        matches!(self, StateRef::Unset)    }     /// Attempt to obtain the string value of this state, or return `None` if there is no such value.    pub fn as_bstr(&self) -> Option<&BStr> {        match self {            StateRef::Value(v) => Some(v.as_bstr()),            _ => None,        }    }} /// Initializationimpl<'a> StateRef<'a> {    /// Keep `input` in one of our enums.    pub fn from_bytes(input: &'a [u8]) -> Self {        Self::Value(ValueRef::from_bytes(input))    }} /// Accessimpl StateRef<'_> {    /// Turn ourselves into our owned counterpart.    pub fn to_owned(self) -> State {        self.into()    }} impl<'a> State {    /// Turn ourselves into our ref-type.    pub fn as_ref(&'a self) -> StateRef<'a> {        match self {            State::Value(v) => StateRef::Value(v.as_ref()),            State::Set => StateRef::Set,            State::Unset => StateRef::Unset,            State::Unspecified => StateRef::Unspecified,        }    }} impl<'a> From<StateRef<'a>> for State {    fn from(s: StateRef<'a>) -> Self {        match s {            StateRef::Value(v) => State::Value(v.into()),            StateRef::Set => State::Set,            StateRef::Unset => State::Unset,            StateRef::Unspecified => State::Unspecified,        }    }}