From a4a7d107fe2c82b1070a72dcf5a6cf5decdaf960 Mon Sep 17 00:00:00 2001 From: Akshay Date: Thu, 19 Mar 2020 17:21:14 +0530 Subject: implement custom path, simpler api --- fondant_derive/src/lib.rs | 73 ++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/fondant_derive/src/lib.rs b/fondant_derive/src/lib.rs index 946c130..0c66d62 100644 --- a/fondant_derive/src/lib.rs +++ b/fondant_derive/src/lib.rs @@ -1,16 +1,15 @@ extern crate proc_macro; use ::std::ffi::{OsStr, OsString}; -use ::std::path::{Path, PathBuf}; -use directories::ProjectDirs; +use ::std::path::Path; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; -use syn::{parse_macro_input, DeriveInput, Error, Ident, Lit, Meta, MetaNameValue, Result}; +use syn::{parse_macro_input, DeriveInput, Ident, Lit, Meta, MetaNameValue}; #[derive(Debug, Default)] struct ConfigPath { - parent: Option, + parent: String, filename: Option, extension: Option, } @@ -33,13 +32,9 @@ fn extract_attributes(ast: &DeriveInput) -> ConfigPath { if let Lit::Str(f) = lit { let f = f.value(); let fp = Path::new(&f); - let blank = Path::new(""); - let parent = match fp.parent() { - Some(blank) => None, - other => other, - }; + let parent = fp.parent().unwrap_or(Path::new("")); return ConfigPath { - parent: parent.map(Path::to_path_buf), + parent: parent.to_str().unwrap().into(), filename: fp.file_stem().map(OsStr::to_os_string), extension: fp.extension().map(OsStr::to_os_string), }; @@ -80,42 +75,53 @@ fn gen_impl(ast: &DeriveInput, cfg_path: ConfigPath) -> TokenStream { let filename = cfg_path .filename - .unwrap_or(OsStr::new("config").to_os_string()); + .unwrap_or(OsStr::new("config").to_os_string()) + .into_string() + .unwrap(); + let filetype = cfg_path .extension - .unwrap_or(OsStr::new("toml").to_os_string()); - - let filename = filename.into_string().unwrap(); - let filetype = filetype.into_string().unwrap(); - - let pkg_name = env!("CARGO_PKG_NAME"); - let project = ProjectDirs::from("rs", "", pkg_name).unwrap(); - let default_dir = project.config_dir(); - let config_dir = cfg_path.parent.as_deref().unwrap_or(default_dir); - - let tip = Path::new(&filename).with_extension(&filetype); - let config_file = [config_dir, tip.as_ref()] - .iter() - .collect::() - .into_os_string() + .unwrap_or(OsStr::new("toml").to_os_string()) .into_string() .unwrap(); - let parent: String = config_dir.to_str().unwrap().into(); + + let parent = cfg_path.parent; let (ser, ser_fn) = pick_serializer(&filetype); - let gen = quote! { - use ::fondant::{Configure, ProjectDirs, toml, serde_json, serde_yaml, FondantError}; + let includes = quote! { + use ::fondant::*; use ::std::option::Option; use ::std::fs::{self, File, OpenOptions}; use ::std::io::prelude::*; use ::std::io::{ ErrorKind::NotFound, Write }; use ::std::ffi::{OsStr, OsString}; use ::std::path::{Path, PathBuf}; + }; + let load_paths = quote! { + let pkg_name = env!("CARGO_PKG_NAME"); + let project = ProjectDirs::from("rs", "", pkg_name).unwrap(); + let default_dir: String = project.config_dir().to_str().unwrap().into(); + + let d = if #parent != "" { #parent.into() } else { default_dir }; + let config_dir: String = expand_tilde(d) + .as_path() + .to_str() + .unwrap() + .into(); + + let tip = Path::new(&#filename).with_extension(&#filetype); + let mut config_file = PathBuf::from(&config_dir); + config_file.push(tip); + }; + + let gen = quote! { + #includes impl Configure for #struct_ident { fn load() -> Result<#struct_ident, FondantError> { - match File::open(&#config_file) { + #load_paths + match File::open(&config_file) { Ok(mut cfg) => { let mut cfg_data = String::new(); cfg.read_to_string(&mut cfg_data); @@ -125,7 +131,9 @@ fn gen_impl(ast: &DeriveInput, cfg_path: ConfigPath) -> TokenStream { return Ok(config); }, Err(ref e) if e.kind() == NotFound => { - fs::create_dir_all(#parent).map_err(FondantError::DirCreateErr)?; + if !Path::new(&config_dir).is_dir() { + fs::create_dir_all(config_dir).map_err(FondantError::DirCreateErr)?; + } let default_impl = #struct_ident::default(); Configure::store(&default_impl)?; return Ok(default_impl); @@ -134,11 +142,12 @@ fn gen_impl(ast: &DeriveInput, cfg_path: ConfigPath) -> TokenStream { }; } fn store(&self) -> Result<(), FondantError> { + #load_paths let mut f = OpenOptions::new() .write(true) .create(true) .truncate(true) - .open(#config_file) + .open(config_file) .map_err(|_| FondantError::FileOpenError)?; let s = #ser::#ser_fn(self).map_err(|_| FondantError::ConfigParseError)?; -- cgit v1.2.3