use bstr::{BStr, ByteSlice};
use kstring::{KString, KStringRef};
use crate::{State, StateRef};
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Value(KString);
#[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))] KStringRef<'a>);
impl<'a> ValueRef<'a> {
pub fn from_bytes(input: &'a [u8]) -> Self {
Self(KStringRef::from_ref(
#[allow(unsafe_code)]
unsafe {
std::str::from_utf8_unchecked(input)
},
))
}
}
impl ValueRef<'_> {
pub fn as_bstr(&self) -> &BStr {
self.0.as_bytes().as_bstr()
}
pub fn to_owned(self) -> Value {
self.into()
}
}
impl<'a> From<&'a str> for ValueRef<'a> {
fn from(v: &'a str) -> Self {
ValueRef(v.into())
}
}
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(KString::from_ref(v))
}
}
impl Value {
pub fn as_ref(&self) -> ValueRef<'_> {
ValueRef(self.0.as_ref())
}
}
impl StateRef<'_> {
pub fn is_unspecified(&self) -> bool {
matches!(self, StateRef::Unspecified)
}
pub fn is_set(&self) -> bool {
matches!(self, StateRef::Set | StateRef::Value(_))
}
pub fn is_unset(&self) -> bool {
matches!(self, StateRef::Unset)
}
pub fn as_bstr(&self) -> Option<&BStr> {
match self {
StateRef::Value(v) => Some(v.as_bstr()),
_ => None,
}
}
}
impl<'a> StateRef<'a> {
pub fn from_bytes(input: &'a [u8]) -> Self {
Self::Value(ValueRef::from_bytes(input))
}
}
impl<'a> StateRef<'a> {
pub fn to_owned(self) -> State {
self.into()
}
}
impl<'a> State {
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,
}
}
}