Skip to content

Commit

Permalink
improve
Browse files Browse the repository at this point in the history
  • Loading branch information
kingwingfly committed Jun 23, 2024
1 parent 101e358 commit b612941
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 128 deletions.
3 changes: 2 additions & 1 deletion encrypt-config-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ quote = "1.0"

[dev-dependencies]
serde = { version = "1", features = ["derive"] }
encrypt_config = { workspace = true }
encrypt_config = { workspace = true, features = ["derive"] }


[features]
default = []
Expand Down
4 changes: 2 additions & 2 deletions encrypt-config-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn derive_normal_source(input: TokenStream) -> TokenStream {
/// Derive macro for `PersistSource`.
/// # Example
/// ```no_run
/// # use encrypt_config_derive::PersistSource;
/// # use encrypt_config::PersistSource;
/// # use serde::{Deserialize, Serialize};
/// #[derive(Serialize, Deserialize, Default, PersistSource)]
#[cfg_attr(
Expand All @@ -56,7 +56,7 @@ pub fn derive_persist_source(input: TokenStream) -> TokenStream {
/// Derive macro for `SecretSource`.
/// # Example
/// ```no_run
/// # use encrypt_config_derive::SecretSource;
/// # use encrypt_config::SecretSource;
/// # use serde::{Deserialize, Serialize};
/// #[derive(Serialize, Deserialize, Default, SecretSource)]
#[cfg_attr(
Expand Down
4 changes: 2 additions & 2 deletions encrypt-config-derive/src/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ pub(crate) fn derive_normal_source(input: TokenStream) -> TokenStream {
impl #impl_generics ::encrypt_config::NormalSource for #name #ty_generics #where_clause { }

impl #impl_generics ::encrypt_config::Source for #name #ty_generics #where_clause {
fn load() -> Self
fn load() -> ::encrypt_config::error::ConfigResult<Self>
where
Self: Sized,
{
Self::default()
Ok(Self::default())
}

fn save(&self) -> ::encrypt_config::error::ConfigResult<()> {
Expand Down
5 changes: 2 additions & 3 deletions encrypt-config-derive/src/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,16 @@ pub(crate) fn derive_persist_source(input: TokenStream) -> TokenStream {
impl #impl_generics ::encrypt_config::PersistSource for #name #ty_generics #where_clause {
#[cfg(not(feature = "default_config_dir"))]
const PATH: &'static str = #path_or_name;

#[cfg(feature = "default_config_dir")]
const NAME: &'static str = #path_or_name;
}

impl #impl_generics ::encrypt_config::Source for #name #ty_generics #where_clause {
fn load() -> Self
fn load() -> ::encrypt_config::error::ConfigResult<Self>
where
Self: Sized,
{
<Self as ::encrypt_config::PersistSource>::load().unwrap_or_default()
<Self as ::encrypt_config::PersistSource>::load()
}

fn save(&self) -> ::encrypt_config::error::ConfigResult<()> {
Expand Down
6 changes: 2 additions & 4 deletions encrypt-config-derive/src/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,17 @@ pub(crate) fn derive_secret_source(input: TokenStream) -> TokenStream {
impl #impl_generics ::encrypt_config::SecretSource for #name #ty_generics #where_clause {
#[cfg(not(feature = "default_config_dir"))]
const PATH: &'static str = #path_or_name;

#[cfg(feature = "default_config_dir")]
const NAME: &'static str = #path_or_name;

const KEYRING_ENTRY: &'static str = #keyring_entry;
}

impl #impl_generics ::encrypt_config::Source for #name #ty_generics #where_clause {
fn load() -> Self
fn load() -> ::encrypt_config::error::ConfigResult<Self>
where
Self: Sized,
{
<Self as ::encrypt_config::SecretSource>::load().unwrap_or_default()
<Self as ::encrypt_config::SecretSource>::load()
}

fn save(&self) -> ::encrypt_config::error::ConfigResult<()> {
Expand Down
4 changes: 2 additions & 2 deletions encrypt-config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ macro_rules! impl_savaload {

#[allow(non_snake_case)]
fn load_to(cache: &mut Cache) {
$(let $t = $t::load();)+
$(let $t = $t::load_or_default();)+
$(cache.insert(
TypeId::of::<$t>(),
CacheValue {
Expand All @@ -246,7 +246,7 @@ where
}

fn load_to(cache: &mut Cache) {
let t = T::load();
let t = T::load_or_default();
cache.insert(
TypeId::of::<T>(),
CacheValue {
Expand Down
10 changes: 7 additions & 3 deletions encrypt-config/src/encrypt_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{
sync::{OnceLock, RwLock},
};

/// Encrypter struct.
#[derive(serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(PartialEq, Debug))]
pub struct Encrypter {
Expand All @@ -28,7 +29,8 @@ impl Default for Encrypter {
}

impl Encrypter {
pub(crate) fn new(secret_name: impl AsRef<str>) -> ConfigResult<&'static Self> {
/// Create a new encrypter. Load if exists, otherwise create and save a new one.
pub fn new(secret_name: impl AsRef<str>) -> ConfigResult<&'static Self> {
static ENCRYPTERS: OnceLock<RwLock<HashMap<String, &'static Encrypter>>> = OnceLock::new();
let encrypters = ENCRYPTERS.get_or_init(|| RwLock::new(HashMap::new()));
{
Expand Down Expand Up @@ -64,7 +66,8 @@ impl Encrypter {
}
}

pub(crate) fn encrypt<T: serde::Serialize>(&self, to_encrypt: &T) -> ConfigResult<Vec<u8>> {
/// Serialize and encrypt a value.
pub fn encrypt<T: serde::Serialize>(&self, to_encrypt: &T) -> ConfigResult<Vec<u8>> {
let origin = serde_json::to_vec(to_encrypt)?;
self.encrypt_serded(&origin)
}
Expand All @@ -83,7 +86,8 @@ impl Encrypter {
Ok(encrypted)
}

pub(crate) fn decrypt<T>(&self, encrypted: &[u8]) -> ConfigResult<T>
/// Decrypt and deserialize a value.
pub fn decrypt<T>(&self, encrypted: &[u8]) -> ConfigResult<T>
where
for<'de> T: serde::Deserialize<'de>,
{
Expand Down
5 changes: 1 addition & 4 deletions encrypt-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,9 @@ pub const TEST_OUT_DIR: &str = concat!(env!("OUT_DIR"), "/encrypt_config_cache")

pub mod config;
#[cfg(feature = "secret")]
mod encrypt_utils;
pub mod encrypt_utils;
pub mod error;
pub mod source;

pub use config::Config;
pub use source::*;

#[cfg(feature = "derive")]
pub use encrypt_config_derive::*;
122 changes: 109 additions & 13 deletions encrypt-config/src/source/mod.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,123 @@
//! Source module for the encrypt-config crate.

mod normal;
#[cfg(feature = "persist")]
mod persist;
#[cfg(feature = "secret")]
mod secret;

pub use normal::*;
#[cfg(feature = "persist")]
pub use persist::*;
#[cfg(feature = "secret")]
pub use secret::*;

use crate::encrypt_utils::Encrypter;
use crate::error::ConfigResult;
#[cfg(feature = "derive")]
pub use encrypt_config_derive::*;
#[cfg(feature = "persist")]
use serde::{de::DeserializeOwned, Serialize};
#[cfg(feature = "persist")]
use std::path::PathBuf;

/// Source trait for the encrypt-config crate. You can impl your logic for loading and saving the configuration here.
/// Moreover, you can use derive macros to implement [`NormalSource`], [`PersistSource`], and [`SecretSource`] in this crate.
/// In provided ways, `Source` will be implemented when deriving, so that derived structs can be accepted by the [`Config`](crate::Config) struct.
pub trait Source: Default {
/// Load logic for the source, return default value is recommended.
fn load() -> Self
/// Try to load the source, return error if failed.
fn load() -> ConfigResult<Self>
where
Self: Sized;
/// Save logic for the source.
fn save(&self) -> ConfigResult<()>;

/// Load logic for the source, return default value if failed.
fn load_or_default() -> Self
where
Self: Sized,
{
Self::load().unwrap_or_default()
}
}

/// Normal source trait.
pub trait NormalSource: Source {}

/// Persist source trait.
#[cfg(feature = "persist")]
pub trait PersistSource: Source + Serialize + DeserializeOwned {
/// Path for the persist source.
#[cfg(not(feature = "default_config_dir"))]
const PATH: &'static str;
/// Name for the persist source.
#[cfg(feature = "default_config_dir")]
const NAME: &'static str;

/// Path for the persist source.
fn path() -> PathBuf {
#[cfg(not(feature = "default_config_dir"))]
{
PathBuf::from(Self::PATH)
}
#[cfg(feature = "default_config_dir")]
{
dirs::config_dir()
.expect("Default config dir unknown in your OS.")
.join(Self::NAME)
}
}
/// Load the persist source.
fn load() -> ConfigResult<Self> {
let path = Self::path();
let file = std::fs::File::open(path)?;
Ok(serde_json::from_reader(file)?)
}
/// Save the persist source.
fn save(&self) -> ConfigResult<()> {
let path = Self::path();
let parent = path.parent().unwrap();
std::fs::create_dir_all(parent).unwrap();
let file = std::fs::File::create(path).unwrap();
serde_json::to_writer(file, self)?;
Ok(())
}
}

/// Secret source trait.
#[cfg(feature = "secret")]
pub trait SecretSource: Source + Serialize + DeserializeOwned {
/// Path for the persist source.
#[cfg(not(feature = "default_config_dir"))]
const PATH: &'static str;
/// Name for the persist source.
#[cfg(feature = "default_config_dir")]
const NAME: &'static str;
/// Keyring entry for the secret source.
const KEYRING_ENTRY: &'static str;

/// Path for the persist source.
fn path() -> PathBuf {
#[cfg(not(feature = "default_config_dir"))]
{
PathBuf::from(Self::PATH)
}
#[cfg(feature = "default_config_dir")]
{
dirs::config_dir()
.expect("Default config dir unknown in your OS.")
.join(Self::NAME)
}
}
/// Load the secret source.
fn load() -> ConfigResult<Self> {
let path = Self::path();
let encrypter = Encrypter::new(Self::KEYRING_ENTRY)?;
let file = std::fs::File::open(path)?;
let encrypted: Vec<u8> = std::io::Read::bytes(file).collect::<Result<_, _>>()?;
encrypter.decrypt(&encrypted)
}
/// Save the secret source.
fn save(&self) -> ConfigResult<()> {
use std::io::Write as _;

let path = Self::path();
let parent = path.parent().unwrap();
std::fs::create_dir_all(parent).unwrap();
let encrypter = Encrypter::new(Self::KEYRING_ENTRY)?;
let encrypted = encrypter.encrypt(self)?;
let mut file = std::fs::File::create(path).unwrap();
file.write_all(&encrypted)?;
file.flush()?;
Ok(())
}
}
2 changes: 0 additions & 2 deletions encrypt-config/src/source/normal.rs

This file was deleted.

42 changes: 0 additions & 42 deletions encrypt-config/src/source/persist.rs

This file was deleted.

50 changes: 0 additions & 50 deletions encrypt-config/src/source/secret.rs

This file was deleted.

0 comments on commit b612941

Please sign in to comment.