1
Fork 0
mirror of https://github.com/Steffo99/micronfig.git synced 2024-11-25 17:44:18 +00:00

Write some tests and fix some issues

This commit is contained in:
Steffo 2024-01-03 02:52:18 +01:00
parent b98d2da4e9
commit 22838a6cba
Signed by: steffo
GPG key ID: 2A24051445686895
9 changed files with 63 additions and 59 deletions

View file

@ -3,6 +3,7 @@
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/micronfig/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />

View file

@ -51,15 +51,14 @@ impl Cache {
value value
} }
/// Register a new `.env` file in the cache. /// Register a new `.env` file in the cache, if it exists.
///
/// Equivalent to adding an item to [`Cache::envdot`].
#[cfg(feature = "envdot")] #[cfg(feature = "envdot")]
pub fn register_dotenv<Path>(&mut self, path: Path) pub fn register_dotenv<Path>(&mut self, path: Path)
where Path: AsRef<std::path::Path> + Debug where Path: AsRef<std::path::Path> + Debug
{ {
self.envdot.push( let dotenv = crate::envdot::parse_dotenv(path);
crate::envdot::parse_dotenv(path) if let Some(dotenv) = dotenv {
); self.envdot.push(dotenv);
}
} }
} }

View file

@ -12,11 +12,12 @@ use regex::Regex;
pub type DotEnv = HashMap<OsString, String>; pub type DotEnv = HashMap<OsString, String>;
/// Parse a `.env` file. /// Parse a `.env` file.
pub fn parse_dotenv<P>(value: P) -> DotEnv ///
/// Returns [`None`] if no such file is found.
pub fn parse_dotenv<P>(value: P) -> Option<DotEnv>
where P: AsRef<Path> + Debug where P: AsRef<Path> + Debug
{ {
let mut file = File::open(&value) let mut file = File::open(&value).ok()?;
.expect(&*format!("to be able to open {value:?}"));
let mut contents: String = String::new(); let mut contents: String = String::new();
file.read_to_string(&mut contents) file.read_to_string(&mut contents)
@ -64,7 +65,7 @@ pub fn parse_dotenv<P>(value: P) -> DotEnv
}) })
.map(|(key, value)| keys.insert(key, value)); .map(|(key, value)| keys.insert(key, value));
keys Some(keys)
} }
/// Get the requested variable from a [`DotEnv`] structure. /// Get the requested variable from a [`DotEnv`] structure.

View file

@ -19,6 +19,7 @@ quote = "1.0"
[dev-dependencies] [dev-dependencies]
micronfig = { version = "0.3.0", path = "../micronfig" } micronfig = { version = "0.3.0", path = "../micronfig" }
trybuild = "1.0.87"
[lib] [lib]
proc-macro = true proc-macro = true

View file

@ -32,6 +32,7 @@ impl Parse for ConfigItem {
fn parse(input: ParseStream) -> syn::Result<Self> { fn parse(input: ParseStream) -> syn::Result<Self> {
let identifier = input.parse::<Ident>()?; let identifier = input.parse::<Ident>()?;
if input.lookahead1().peek(Token![:]) {
input.parse::<Token![:]>()?; input.parse::<Token![:]>()?;
input.parse::<Type>()?; input.parse::<Type>()?;
@ -42,6 +43,12 @@ impl Parse for ConfigItem {
Ok(Self { identifier, types }) Ok(Self { identifier, types })
} }
else {
let types = vec![];
Ok(Self { identifier, types })
}
}
} }
impl Parse for ConfigPair { impl Parse for ConfigPair {
@ -75,10 +82,12 @@ pub fn config(input: TokenStream) -> TokenStream {
let input: Config = parse_macro_input!(input with syn::punctuated::Punctuated::parse_terminated); let input: Config = parse_macro_input!(input with syn::punctuated::Punctuated::parse_terminated);
let cache_code = quote! { let cache_code = quote! {
#[allow(non_snake_case)]
mod _cache { mod _cache {
pub static lock: std::sync::OnceLock<micronfig::cache::Cache> = std::sync::OnceLock::new(); pub static lock: std::sync::OnceLock<micronfig::cache::Cache> = std::sync::OnceLock::new();
} }
#[allow(non_snake_case)]
fn _cache() -> &'static micronfig::cache::Cache { fn _cache() -> &'static micronfig::cache::Cache {
_cache::lock.get_or_init(micronfig::cache::Cache::new) _cache::lock.get_or_init(micronfig::cache::Cache::new)
} }
@ -124,10 +133,12 @@ pub fn config(input: TokenStream) -> TokenStream {
}; };
quote! { quote! {
#[allow(non_snake_case)]
mod #identifier { mod #identifier {
pub(super) static lock: std::sync::OnceLock<Option<#last_type>> = std::sync::OnceLock::new(); pub(super) static lock: std::sync::OnceLock<Option<#last_type>> = std::sync::OnceLock::new();
} }
#[allow(non_snake_case)]
pub(crate) fn #identifier() -> &'static Option<#last_type> { pub(crate) fn #identifier() -> &'static Option<#last_type> {
#identifier::lock.get_or_init(|| { #identifier::lock.get_or_init(|| {
let key: std::ffi::OsString = #identifier_string.into(); let key: std::ffi::OsString = #identifier_string.into();
@ -154,7 +165,5 @@ pub fn config(input: TokenStream) -> TokenStream {
#items_code #items_code
}; };
println!("{quote}");
quote.into() quote.into()
} }

View file

@ -1,41 +0,0 @@
use micronfig_macros::config;
#[test]
fn basic() {
config! {
GARAS: String,
AUTO: String,
BUS: String,
}
}
#[test]
fn empty() {
config! {}
}
#[test]
fn conversion_simple() {
config! {
GARAS: String > u32,
AUTO: String > u16,
}
}
/*
#[test]
fn implicit() {
config! {
GARAS,
AUTO,
}
}
#[test]
fn conversion_implicit() {
config! {
GARAS: > u32,
AUTO > u16,
}
}
*/

View file

@ -0,0 +1,7 @@
micronfig::config! {
}
fn main() {
}

View file

@ -0,0 +1,7 @@
micronfig::config! {
GARASAUTO: String,
}
fn main() {
println!("{:?}", GARASAUTO())
}

View file

@ -0,0 +1,20 @@
macro_rules! pass {
($id:ident) => {
#[test]
fn $id() {
trybuild::TestCases::new().pass(format!("tests/sources/{}.rs", stringify!($id)));
}
}
}
macro_rules! fail {
($id:ident) => {
#[test]
fn $id() {
trybuild::TestCases::new().compile_fail(format!("tests/sources/{}.rs", stringify!($id)));
}
}
}
pass!(empty);
pass!(string_single_explicit);