de_env 1.0.0

Deserialize environment variables into a struct
Documentation
use std::{
    borrow::Cow,
    ffi::{OsStr, OsString},
};

use crate::{Error, Result};

pub struct Key<'de>(Cow<'de, OsStr>);

impl<'de> From<Cow<'de, OsStr>> for Key<'de> {
    fn from(value: Cow<'de, OsStr>) -> Self {
        Self(value)
    }
}

impl<'de> From<&'de OsStr> for Key<'de> {
    fn from(value: &'de OsStr) -> Self {
        Self::from(Cow::from(value))
    }
}

impl<'de> From<OsString> for Key<'de> {
    fn from(value: OsString) -> Self {
        Self::from(Cow::from(value))
    }
}

impl<'de> From<Cow<'de, str>> for Key<'de> {
    fn from(value: Cow<'de, str>) -> Self {
        match value {
            Cow::Owned(string) => Self(Cow::Owned(OsString::from(string))),
            Cow::Borrowed(str) => Self(Cow::Borrowed(OsStr::new(str))),
        }
    }
}

impl<'de> From<&'de str> for Key<'de> {
    fn from(value: &'de str) -> Self {
        Self(Cow::Borrowed(OsStr::new(value)))
    }
}

impl<'de> From<String> for Key<'de> {
    fn from(value: String) -> Self {
        Self(Cow::Owned(OsString::from(value)))
    }
}

impl<'de> serde::de::IntoDeserializer<'de, Error> for Key<'de> {
    type Deserializer = Self;

    fn into_deserializer(self) -> Self::Deserializer {
        self
    }
}

impl<'de> serde::de::Deserializer<'de> for Key<'de> {
    type Error = Error;

    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
    where
        V: serde::de::Visitor<'de>,
    {
        match self.0.to_str() {
            Some(str) => visitor.visit_str(str),
            None => Err(Error::invalid_unicode(self.0.into_owned())),
        }
    }

    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
    where
        V: serde::de::Visitor<'de>,
    {
        visitor.visit_string(
            self.0
                .into_owned()
                .into_string()
                .map_err(Error::invalid_unicode)?,
        )
    }

    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
    where
        V: serde::de::Visitor<'de>,
    {
        self.deserialize_str(visitor)
    }

    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
    where
        V: serde::de::Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    crate::de::util::unsupported_types! {
        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char
        bytes byte_buf option unit unit_struct seq tuple
        tuple_struct map struct enum ignored_any any
    }
}