Struct serde_env_field::EnvField
source · pub struct EnvField<T, Variant = UseFromStr>(/* private fields */);
Expand description
A field that deserializes either as T
or as String
with all environment variables expanded via the shellexpand
crate.
By default, it requires T
to implement the FromStr
trait
for deserialization from String
after environment variables expansion.
You can use the UseDeserialize
to bypass the FromStr
and deserialize the T
directly from the string with all environment variables expanded.
The EnvField
serializes transparently as the T
type if the T
is serializable.
Works nicely with Option
, Vec
, and #[serde(default)]
.
Note: if you want to wrap all the fields of a struct or an enum
with the EnvField
, you might want to use the env_field_wrap
attribute.
Examples
Basic
#[derive(Serialize, Deserialize)]
struct Example {
name: EnvField<String>,
size: EnvField<usize>,
num: EnvField<i32>,
}
std::env::set_var("SIZE", "100");
let de: Example = toml::from_str(r#"
name = "${NAME:-Default Name}"
size = "$SIZE"
num = 42
"#).unwrap();
assert_eq!(&de.name, "Default Name");
assert_eq!(de.size, 100);
assert_eq!(de.num, 42);
Optional fields
#[derive(Serialize, Deserialize)]
struct Example {
required: EnvField<i32>,
optional: Option<EnvField<i32>>,
}
let de: Example = toml::from_str(r#"
required = 512
"#).unwrap();
assert_eq!(de.required, 512);
assert!(de.optional.is_none());
std::env::set_var("OPTIONAL", "-1024");
let de: Example = toml::from_str(r#"
required = 512
optional = "$OPTIONAL"
"#).unwrap();
assert_eq!(de.required, 512);
assert_eq!(de.optional.unwrap(), -1024);
let de: Example = toml::from_str(r#"
required = 512
optional = 42
"#).unwrap();
assert_eq!(de.required, 512);
assert_eq!(de.optional.unwrap(), 42);
Sequences
#[derive(Serialize, Deserialize)]
struct Example {
seq: Vec<EnvField<i32>>,
}
std::env::set_var("NUM", "1000");
let de: Example = toml::from_str(r#"
seq = [
12, "$NUM", 145,
]
"#).unwrap();
assert_eq!(de.seq[0], 12);
assert_eq!(de.seq[1], 1000);
assert_eq!(de.seq[2], 145);
Defaults
use derive_more::FromStr;
#[derive(Serialize, Deserialize)]
struct Example {
#[serde(default)]
num: EnvField<NumWithDefault>,
}
#[derive(Serialize, Deserialize, FromStr)]
#[serde(transparent)]
struct NumWithDefault(i32);
impl Default for NumWithDefault {
fn default() -> Self {
Self(42)
}
}
let de: Example = toml::from_str("").unwrap();
assert_eq!(de.num.0, 42);
let de: Example = toml::from_str(r#"
num = 100
"#).unwrap();
assert_eq!(de.num.0, 100);
std::env::set_var("SOME_NUM", "555");
let de: Example = toml::from_str(r#"
num = "$SOME_NUM"
"#).unwrap();
assert_eq!(de.num.0, 555);
Deserialization without FromStr
use serde_env_field::UseDeserialize;
#[derive(Serialize, Deserialize)]
struct Example {
variant: EnvField<Variants, UseDeserialize>
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
enum Variants {
AUsefullVariant,
AnotherCoolVariant,
}
let de: Example = toml::from_str(r#"
variant = "a-usefull-variant"
"#).unwrap();
assert!(matches!(*de.variant, Variants::AUsefullVariant));
std::env::set_var("SELECTED_VARIANT", "another-cool-variant");
let de: Example = toml::from_str(r#"
variant = "$SELECTED_VARIANT"
"#).unwrap();
assert!(matches!(*de.variant, Variants::AnotherCoolVariant));
Deserialization with FromStr
#[derive(Serialize, Deserialize)]
struct Example {
inner: EnvField<Inner>,
}
#[derive(Serialize, Deserialize)]
struct Inner {
// We can use `EnvField` in inner structs
num: EnvField<i32>,
sym: EnvField<String>,
}
impl FromStr for Inner {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut split = s.split(';');
let num = split
.next()
.unwrap()
.parse()
.map_err(|err: ParseIntError| err.to_string())?;
let sym = split
.next()
.unwrap()
.to_string()
.into();
Ok(Self {
num,
sym
})
}
}
std::env::set_var("INNER_NUM", "2048");
std::env::set_var("INNER_SYM", "Hi");
let de: Example = toml::from_str(r#"
inner = "$INNER_NUM;$INNER_SYM"
"#).unwrap();
assert_eq!(de.inner.num, 2048);
assert_eq!(&de.inner.sym, "Hi");
let de: Example = toml::from_str(r#"
[inner]
num = -500
sym = "Hello"
"#).unwrap();
assert_eq!(de.inner.num, -500);
assert_eq!(&de.inner.sym, "Hello");
Implementations§
source§impl<T, V> EnvField<T, V>
impl<T, V> EnvField<T, V>
sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Unwraps the value, consuming the env field.
Trait Implementations§
source§impl<T: AddAssign, V> AddAssign<T> for EnvField<T, V>
impl<T: AddAssign, V> AddAssign<T> for EnvField<T, V>
source§fn add_assign(&mut self, rhs: T)
fn add_assign(&mut self, rhs: T)
Performs the
+=
operation. Read moresource§impl<T: AddAssign, V> AddAssign for EnvField<T, V>
impl<T: AddAssign, V> AddAssign for EnvField<T, V>
source§fn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
Performs the
+=
operation. Read moresource§impl<T: BitAndAssign, V> BitAndAssign<T> for EnvField<T, V>
impl<T: BitAndAssign, V> BitAndAssign<T> for EnvField<T, V>
source§fn bitand_assign(&mut self, rhs: T)
fn bitand_assign(&mut self, rhs: T)
Performs the
&=
operation. Read moresource§impl<T: BitAndAssign, V> BitAndAssign for EnvField<T, V>
impl<T: BitAndAssign, V> BitAndAssign for EnvField<T, V>
source§fn bitand_assign(&mut self, rhs: Self)
fn bitand_assign(&mut self, rhs: Self)
Performs the
&=
operation. Read moresource§impl<T: BitOrAssign, V> BitOrAssign<T> for EnvField<T, V>
impl<T: BitOrAssign, V> BitOrAssign<T> for EnvField<T, V>
source§fn bitor_assign(&mut self, rhs: T)
fn bitor_assign(&mut self, rhs: T)
Performs the
|=
operation. Read moresource§impl<T: BitOrAssign, V> BitOrAssign for EnvField<T, V>
impl<T: BitOrAssign, V> BitOrAssign for EnvField<T, V>
source§fn bitor_assign(&mut self, rhs: Self)
fn bitor_assign(&mut self, rhs: Self)
Performs the
|=
operation. Read moresource§impl<T: BitXorAssign, V> BitXorAssign<T> for EnvField<T, V>
impl<T: BitXorAssign, V> BitXorAssign<T> for EnvField<T, V>
source§fn bitxor_assign(&mut self, rhs: T)
fn bitxor_assign(&mut self, rhs: T)
Performs the
^=
operation. Read moresource§impl<T: BitXorAssign, V> BitXorAssign for EnvField<T, V>
impl<T: BitXorAssign, V> BitXorAssign for EnvField<T, V>
source§fn bitxor_assign(&mut self, rhs: Self)
fn bitxor_assign(&mut self, rhs: Self)
Performs the
^=
operation. Read moresource§impl<'de, T> Deserialize<'de> for EnvField<T, UseFromStr>
impl<'de, T> Deserialize<'de> for EnvField<T, UseFromStr>
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
source§impl<'de, T> Deserialize<'de> for EnvField<T, UseDeserialize>where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for EnvField<T, UseDeserialize>where
T: Deserialize<'de>,
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
source§impl<T: DivAssign, V> DivAssign<T> for EnvField<T, V>
impl<T: DivAssign, V> DivAssign<T> for EnvField<T, V>
source§fn div_assign(&mut self, rhs: T)
fn div_assign(&mut self, rhs: T)
Performs the
/=
operation. Read moresource§impl<T: DivAssign, V> DivAssign for EnvField<T, V>
impl<T: DivAssign, V> DivAssign for EnvField<T, V>
source§fn div_assign(&mut self, rhs: Self)
fn div_assign(&mut self, rhs: Self)
Performs the
/=
operation. Read moresource§impl<T: MulAssign, V> MulAssign<T> for EnvField<T, V>
impl<T: MulAssign, V> MulAssign<T> for EnvField<T, V>
source§fn mul_assign(&mut self, rhs: T)
fn mul_assign(&mut self, rhs: T)
Performs the
*=
operation. Read moresource§impl<T: MulAssign, V> MulAssign for EnvField<T, V>
impl<T: MulAssign, V> MulAssign for EnvField<T, V>
source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
Performs the
*=
operation. Read moresource§impl<T: Ord, V> Ord for EnvField<T, V>
impl<T: Ord, V> Ord for EnvField<T, V>
source§impl<T: PartialEq, V> PartialEq for EnvField<T, V>
impl<T: PartialEq, V> PartialEq for EnvField<T, V>
source§impl<T: PartialOrd, V> PartialOrd<T> for EnvField<T, V>
impl<T: PartialOrd, V> PartialOrd<T> for EnvField<T, V>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for
self
and other
) and is used by the <=
operator. Read moresource§impl<T: PartialOrd, V> PartialOrd for EnvField<T, V>
impl<T: PartialOrd, V> PartialOrd for EnvField<T, V>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for
self
and other
) and is used by the <=
operator. Read moresource§impl<T: RemAssign, V> RemAssign<T> for EnvField<T, V>
impl<T: RemAssign, V> RemAssign<T> for EnvField<T, V>
source§fn rem_assign(&mut self, rhs: T)
fn rem_assign(&mut self, rhs: T)
Performs the
%=
operation. Read moresource§impl<T: RemAssign, V> RemAssign for EnvField<T, V>
impl<T: RemAssign, V> RemAssign for EnvField<T, V>
source§fn rem_assign(&mut self, rhs: Self)
fn rem_assign(&mut self, rhs: Self)
Performs the
%=
operation. Read moresource§impl<T: ShlAssign, V> ShlAssign<T> for EnvField<T, V>
impl<T: ShlAssign, V> ShlAssign<T> for EnvField<T, V>
source§fn shl_assign(&mut self, rhs: T)
fn shl_assign(&mut self, rhs: T)
Performs the
<<=
operation. Read moresource§impl<T: ShlAssign, V> ShlAssign for EnvField<T, V>
impl<T: ShlAssign, V> ShlAssign for EnvField<T, V>
source§fn shl_assign(&mut self, rhs: Self)
fn shl_assign(&mut self, rhs: Self)
Performs the
<<=
operation. Read moresource§impl<T: ShrAssign, V> ShrAssign<T> for EnvField<T, V>
impl<T: ShrAssign, V> ShrAssign<T> for EnvField<T, V>
source§fn shr_assign(&mut self, rhs: T)
fn shr_assign(&mut self, rhs: T)
Performs the
>>=
operation. Read moresource§impl<T: ShrAssign, V> ShrAssign for EnvField<T, V>
impl<T: ShrAssign, V> ShrAssign for EnvField<T, V>
source§fn shr_assign(&mut self, rhs: Self)
fn shr_assign(&mut self, rhs: Self)
Performs the
>>=
operation. Read moresource§impl<T: SubAssign, V> SubAssign<T> for EnvField<T, V>
impl<T: SubAssign, V> SubAssign<T> for EnvField<T, V>
source§fn sub_assign(&mut self, rhs: T)
fn sub_assign(&mut self, rhs: T)
Performs the
-=
operation. Read moresource§impl<T: SubAssign, V> SubAssign for EnvField<T, V>
impl<T: SubAssign, V> SubAssign for EnvField<T, V>
source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
Performs the
-=
operation. Read moreimpl<T: Copy, V> Copy for EnvField<T, V>
impl<T: Eq, V> Eq for EnvField<T, V>
Auto Trait Implementations§
impl<T, Variant> RefUnwindSafe for EnvField<T, Variant>where
T: RefUnwindSafe,
Variant: RefUnwindSafe,
impl<T, Variant> Send for EnvField<T, Variant>
impl<T, Variant> Sync for EnvField<T, Variant>
impl<T, Variant> Unpin for EnvField<T, Variant>
impl<T, Variant> UnwindSafe for EnvField<T, Variant>where
T: UnwindSafe,
Variant: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more