Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 33 additions & 28 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::Path;

use serde::de;

use crate::{error::Result, Error};
use crate::{Error, error::Result};

pub fn from_iter<T, Iter>(iter: Iter) -> Result<T>
where
Expand All @@ -12,17 +12,20 @@ where
from_iter_inner::<T, Iter>(None, iter)
}

pub fn from_iter_inner<'a, T, Iter>(prefix: Option<&'a str>, iter: Iter) -> Result<T>
pub fn from_iter_inner<T, Iter>(prefix: Option<&str>, iter: Iter) -> Result<T>
where
T: de::DeserializeOwned,
Iter: IntoIterator<Item = (String, String)>,
{
(if prefix.is_some() {
envy::prefixed(prefix.unwrap().to_uppercase()).from_iter::<_, T>(iter)
} else {
envy::from_iter::<_, T>(iter)
})
.map_err(|e| Error::new(e))
match prefix {
Some(pref) => {
envy::prefixed(pref.to_uppercase()).from_iter::<_, T>(iter)
}
None => {
// No prefix provided, use default behavior
envy::from_iter::<_, T>(iter)
}
}.map_err(Error::new)
}

/// Deserialize program-available environment variables into an instance of type `T`.
Expand Down Expand Up @@ -56,16 +59,18 @@ where
from_env_inner(None)
}

pub fn from_env_inner<'a, T>(prefix: Option<&'a str>) -> Result<T>
pub fn from_env_inner<T>(prefix: Option<&str>) -> Result<T>
where
T: de::DeserializeOwned,
{
(if prefix.is_some() {
envy::prefixed(prefix.unwrap().to_uppercase()).from_env::<T>()
} else {
envy::from_env::<T>()
})
.map_err(|e| Error::new(e))
match prefix {
Some(pref) => {
envy::prefixed(pref.to_uppercase()).from_env::<T>()
}
None => {
envy::from_env::<T>()
}
}.map_err(Error::new)
}

/// Deserialize environment variables from a string into an instance of type `T`.
Expand All @@ -83,7 +88,7 @@ where
/// Ok(())
/// }
/// ```
pub fn from_str<'a, T>(input: &'a str) -> Result<T>
pub fn from_str<T>(input: &str) -> Result<T>
where
T: de::DeserializeOwned,
{
Expand All @@ -96,12 +101,12 @@ where
{
let mut env = Vec::new();

for pair in dotenvy::from_read_iter(input.as_bytes()).into_iter() {
let (key, value) = pair.map_err(|e| Error::new(e))?;
for pair in dotenvy::from_read_iter(input.as_bytes()) {
let (key, value) = pair.map_err(Error::new)?;
env.push((key, value));
}

from_iter_inner::<T, _>(prefix, env.into_iter())
from_iter_inner::<T, _>(prefix, env)
}

/// Deserialize an environment variable file into an instance of type `T`.
Expand All @@ -119,40 +124,40 @@ where
/// Ok(())
/// }
/// ```
pub fn from_file<'a, T>(path: &Path) -> Result<T>
pub fn from_file<T>(path: &Path) -> Result<T>
where
T: de::DeserializeOwned,
{
from_file_inner(None, path)
}

pub fn from_file_inner<'a, T>(prefix: Option<&'a str>, path: &Path) -> Result<T>
pub fn from_file_inner<T>(prefix: Option<&str>, path: &Path) -> Result<T>
where
T: de::DeserializeOwned,
{
let mut env = Vec::new();

for pair in dotenvy::from_filename_iter(path)
.map_err(|e| Error::new(e))?
.into_iter()
.map_err(Error::new)?
{
let (key, value) = pair.map_err(|e| Error::new(e))?;
let (key, value) = pair.map_err(Error::new)?;
env.push((key, value));
}

from_iter_inner::<T, _>(prefix, env.into_iter())
from_iter_inner::<T, _>(prefix, env)
}

#[cfg(test)]
mod tests {
use super::*;
use std::{
env::{set_var, vars},
fs::write,
io::{prelude::*, SeekFrom},
io::{SeekFrom, prelude::*},
};

use tempfile::NamedTempFile;

use super::*;
use crate::Value;

#[test]
Expand Down Expand Up @@ -186,7 +191,7 @@ mod tests {
write(file.path(), input).unwrap();
file.seek(SeekFrom::Start(0)).unwrap();

let env: Value = from_file(&file.path().to_path_buf()).unwrap();
let env: Value = from_file(file.path()).unwrap();

assert_eq!(env.len(), 1);
assert_eq!("world", env.get("hello").unwrap());
Expand Down
1 change: 0 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std;
use std::fmt::{self, Display};

use serde::{de, ser};
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ pub use de::from_env;
pub use de::from_file;
pub use de::from_str;

pub use ser::Serializer;
pub use ser::to_file;
pub use ser::to_string;
pub use ser::Serializer;

pub use value::Value;

pub use prefixed::prefixed;
pub use prefixed::Prefixed;
pub use prefixed::prefixed;

#[cfg(test)]
mod tests {
use crate::{from_str, to_string, Value};
use crate::{Value, from_str, to_string};
use serde::{Deserialize, Serialize};

#[test]
Expand Down
37 changes: 19 additions & 18 deletions src/ser.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use serde::{ser, Serialize};
use std::{fs::write, path::Path};
use crate::error::{Error, Result};
#[cfg(feature = "debug")]
use log::debug;
use crate::error::{Error, Result};
use serde::{Serialize, ser};
use std::{fs::write, path::Path};

#[cfg(not(feature = "debug"))]
macro_rules! debug {
Expand All @@ -23,7 +23,7 @@
fn new(prefix: Option<&str>) -> Self {
Self {
output: String::new(),
base_prefix: prefix.unwrap_or("").to_uppercase().into(),
base_prefix: prefix.unwrap_or("").to_uppercase(),
prefix: "".into(),
key: false,
sequence: false,
Expand Down Expand Up @@ -96,14 +96,14 @@
to_file_inner(None, p, v)
}

pub fn to_file_inner<'a, T>(prefix: Option<&'a str>, p: &Path, v: &T) -> Result<()>
pub fn to_file_inner<T>(prefix: Option<&str>, p: &Path, v: &T) -> Result<()>
where
T: ser::Serialize,
{
write(p, to_string_inner(prefix, v)?).map_err(|e| Error::Message(e.to_string()))
}

impl<'a> ser::Serializer for &'a mut Serializer {
impl ser::Serializer for &mut Serializer {
type Ok = ();
type Error = Error;

Expand Down Expand Up @@ -184,7 +184,7 @@

if self.key {
let mut key = self.base_prefix.clone();
if self.prefix.len() > 0 {
if !self.prefix.is_empty() {
self.prefix.push('_');
}
self.prefix += &v.to_uppercase();
Expand All @@ -198,9 +198,9 @@
}

self.output += &key;
} else if v.len() > 0 {
} else if !v.is_empty() {
self.output += "\"";
self.output += &v;
self.output += v;
self.output += "\"";
}
Ok(())
Expand Down Expand Up @@ -229,7 +229,7 @@
Ok(())
}

fn serialize_unit_struct(self, name: &'static str) -> Result<()> {

Check warning on line 232 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 232 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 232 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`
debug!("serialize unit struct: {}", name);
self.serialize_unit()
}
Expand All @@ -244,7 +244,7 @@
self.serialize_str(variant)
}

fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>

Check warning on line 247 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 247 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 247 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`
where
T: ?Sized + ser::Serialize,
{
Expand Down Expand Up @@ -318,16 +318,16 @@
Ok(self)
}

fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {

Check warning on line 321 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 321 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 321 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`
debug!("serialize struct: {}", name);
self.serialize_map(Some(len))
}

fn serialize_struct_variant(
self,
name: &'static str,

Check warning on line 328 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 328 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`

Check warning on line 328 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `name`
_variant_index: u32,
variant: &'static str,

Check warning on line 330 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `variant`

Check warning on line 330 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `variant`

Check warning on line 330 in src/ser.rs

View workflow job for this annotation

GitHub Actions / test

unused variable: `variant`
len: usize,
) -> Result<Self::SerializeStructVariant> {
debug!("serialize struct variant: {}/{}", name, variant);
Expand All @@ -335,7 +335,7 @@
}
}

impl<'a> ser::SerializeSeq for &'a mut Serializer {
impl ser::SerializeSeq for &mut Serializer {
type Ok = ();
type Error = Error;

Expand All @@ -358,7 +358,7 @@
}
}

impl<'a> ser::SerializeTuple for &'a mut Serializer {
impl ser::SerializeTuple for &mut Serializer {
type Ok = ();
type Error = Error;

Expand All @@ -381,7 +381,7 @@
}
}

impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
impl ser::SerializeTupleStruct for &mut Serializer {
type Ok = ();
type Error = Error;

Expand All @@ -403,7 +403,7 @@
}
}

impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
impl ser::SerializeTupleVariant for &mut Serializer {
type Ok = ();
type Error = Error;

Expand All @@ -425,7 +425,7 @@
}
}

impl<'a> ser::SerializeMap for &'a mut Serializer {
impl ser::SerializeMap for &mut Serializer {
type Ok = ();
type Error = Error;

Expand All @@ -452,7 +452,7 @@
}
}

impl<'a> ser::SerializeStruct for &'a mut Serializer {
impl ser::SerializeStruct for &mut Serializer {
type Ok = ();
type Error = Error;

Expand All @@ -472,7 +472,7 @@
}
}

impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
impl ser::SerializeStructVariant for &mut Serializer {
type Ok = ();
type Error = Error;

Expand Down Expand Up @@ -546,7 +546,7 @@
use std::fs::read_to_string;
use tempfile::NamedTempFile;

use crate::{from_str, Value};
use crate::{Value, from_str};

#[test]
fn to_string_test() {
Expand All @@ -564,7 +564,7 @@
env.insert("HELLO".into(), "WORLD".into());

let file = NamedTempFile::new().unwrap();
to_file(&file.path(), &env).unwrap();
to_file(file.path(), &env).unwrap();
let s = read_to_string(file.path()).unwrap();

assert_eq!("HELLO=\"WORLD\"", s);
Expand Down Expand Up @@ -613,6 +613,7 @@
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[allow(clippy::upper_case_acronyms)]
enum EnumTestEnum {
HELLO,
WORLD,
Expand Down
14 changes: 6 additions & 8 deletions src/value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! The Value object, a loosely typed way of representing any valid envfile content.

cfg_if::cfg_if! {
if #[cfg(feature = "preserve_order")] {
use indexmap::IndexMap as Map;
Expand Down Expand Up @@ -30,6 +28,12 @@ cfg_if::cfg_if! {
#[serde(transparent)]
pub struct Value(Map<String, String>);

impl Default for Value {
fn default() -> Self {
Self::new()
}
}

impl Value {
/// Create an empty [`Value`].
///
Expand All @@ -39,12 +43,6 @@ impl Value {
}
}

impl Default for Value {
fn default() -> Self {
Self::new()
}
}

impl std::ops::Deref for Value {
type Target = Map<String, String>;

Expand Down