Skip to content

Commit

Permalink
Merge pull request #3 from bloodnighttw/utils/save-path
Browse files Browse the repository at this point in the history
Utils/save path
  • Loading branch information
bloodnighttw authored Jul 13, 2024
2 parents a07f7f6 + dff7a57 commit 2c485e6
Show file tree
Hide file tree
Showing 8 changed files with 620 additions and 10 deletions.
10 changes: 6 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members=[
resolver = "2"

[workspace.package]
version = "0.1.3" # Don't forget to update this version to dependencies in [workspace.dependencies] reginleif-utils and reginleif-macro
version = "0.2.0-alpha-1" # Don't forget to update this version to dependencies in [workspace.dependencies] reginleif-utils and reginleif-macro
license = "Apache-2.0"
description = "The core library of nolauncher."
readme = "README.md"
Expand All @@ -23,5 +23,5 @@ tokio = { version = "1.38.0", features = ["full"] }
async-trait = "0.1.81"
reqwest = { version = "0.12.5", features = ["json"] }
thiserror = "1.0.61"
reginleif-utils = {path = "reginleif-utils", version = "0.1.3"} # Same version as workspace
reginleif-macro = {path = "reginleif-macro", version = "0.1.3"} # Same version as workspace
reginleif-utils = {path = "reginleif-utils", version = "0.2.0-alpha-1"} # Same version as workspace
reginleif-macro = {path = "reginleif-macro", version = "0.2.0-alpha-1"} # Same version as workspace
148 changes: 147 additions & 1 deletion reginleif-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use proc_macro::TokenStream;
use syn::ItemStruct;
use syn::{DeriveInput, ItemStruct, Meta};

fn impl_expire(ast:ItemStruct) -> TokenStream{
let ident = ast.ident;
Expand Down Expand Up @@ -52,3 +52,149 @@ pub fn refresh_panic(item:TokenStream) -> TokenStream{

token.into()
}

#[proc_macro_derive(BaseStorePoint)]
pub fn base_store_point(item:TokenStream) -> TokenStream{
let ast:ItemStruct = syn::parse(item).unwrap();
let ident = ast.ident;
let token = quote::quote! {
impl reginleif_utils::save_path::BaseStorePoint for #ident{
fn get_base(&self) -> std::path::PathBuf {
self.0.clone()
}
}
};

token.into()
}

fn impl_storage(ast:DeriveInput) -> TokenStream{
let ident = ast.ident;

let filepath = ast.attrs.iter().filter(
|x| x.path().is_ident("filepath")
).nth(0).expect("required #[filepath(&'static [&static str])] to use this derive!");

let filepath = match &filepath.meta {
Meta::List(a) => a.tokens.clone(),
_o=> panic!("error while parsing argument!")
};

let base_on = ast.attrs.iter().filter(
|x| x.path().is_ident("base_on")
).nth(0);

return if let Some(base_on) = base_on {
let base_on = match &base_on.meta {
Meta::List(a) => a.tokens.clone(),
_o=> panic!("error while parsing argument!")
};


let token = quote::quote! {
impl reginleif_utils::save_path::Store for #ident{
const FILE_PATH: &'static [&'static str] = #filepath;
type AcceptStorePoint = #base_on;
}
};
token.into()
}else{ // this mean we are declared a generic struct.
let token = quote::quote! {
impl<T> reginleif_utils::save_path::Store for #ident<T>
where T: reginleif_utils::save_path::BaseStorePoint{
const FILE_PATH: &'static [&'static str] = #filepath;
type AcceptStorePoint = T;
}
};
token.into()

}

}

#[proc_macro_derive(Storage, attributes(base_on,filepath))]
pub fn storage(item: TokenStream) -> TokenStream {
let ast:DeriveInput = syn::parse(item).unwrap();
let implement = impl_storage(ast);
implement
}

fn impl_save(ast: DeriveInput) -> TokenStream{
let ident = ast.ident;
let base_on = ast.attrs.iter().filter(
|x| x.path().is_ident("base_on")
).nth(0);

if let Some(base_on) = base_on {
let base_on = match &base_on.meta {
Meta::List(a) => a.tokens.clone(),
_o=> panic!("error while parsing argument!")
};

let token = quote::quote! {
impl reginleif_utils::save_path::Save for #ident{
type AcceptStorePoint = #base_on;
}
};

token.into()
} else { // this mean we are declared a generic struct.
let token = quote::quote! {
impl<T> reginleif_utils::save_path::Save for #ident<T>
where T: reginleif_utils::save_path::BaseStorePoint{
type AcceptStorePoint = T;
}
};

token.into()
}

}

#[proc_macro_derive(Save, attributes(base_on))]
pub fn save(item: TokenStream) -> TokenStream {
let ast:DeriveInput = syn::parse(item).unwrap();
let implement = impl_save(ast);
implement
}

fn impl_load(ast: DeriveInput) -> TokenStream{
let ident = ast.ident;
let base_on = ast.attrs.iter().filter(
|x| x.path().is_ident("base_on")
).nth(0);

if let Some(base_on) = base_on {
let base_on = match &base_on.meta {
Meta::List(a) => a.tokens.clone(),
_o=> panic!("error while parsing argument!")
};

let token = quote::quote! {
impl reginleif_utils::save_path::Load for #ident{
type AcceptStorePoint = #base_on;
}
};

token.into()
} else { // this mean we are declared a generic struct.
let token = quote::quote! {
impl<T> reginleif_utils::save_path::Load for #ident<T>
where T: reginleif_utils::save_path::BaseStorePoint{
type AcceptStorePoint = T;
}
};

token.into()

}

}


#[proc_macro_derive(Load, attributes(base_on))]
pub fn load(item: TokenStream) -> TokenStream {
let ast:DeriveInput = syn::parse(item).unwrap();
let implement = impl_load(ast);
implement
}
4 changes: 3 additions & 1 deletion reginleif-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ reginleif-macro = {path = "../reginleif-macro"} # to test package, so not depend
tokio.workspace = true
reqwest.workspace = true
async-trait.workspace = true
anyhow.workspace = true
anyhow.workspace = true
serde.workspace = true
serde_json.workspace = true
3 changes: 2 additions & 1 deletion reginleif-test/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod expiring_data;
mod expiring_data;
mod save_path;
117 changes: 117 additions & 0 deletions reginleif-test/src/utils/save_path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#[cfg(test)]
mod test{
use std::marker::PhantomData;
use std::path::{PathBuf};
use serde::{Deserialize, Serialize};
use reginleif_macro::{BaseStorePoint, Load, Save, Storage};
use reginleif_utils::save_path::{BaseStorePoint, ExpandStorePoint, Load, Save, Store};


#[derive(BaseStorePoint,PartialEq,Debug)]
struct TestPath(PathBuf);

impl From<PathBuf> for TestPath{
fn from(path:PathBuf) -> Self{
Self(path)
}
}

#[derive(Deserialize,Serialize,PartialEq,Debug,Storage)]
#[base_on(TestPath)] #[filepath(&["test.txt"])]
struct A;

#[tokio::test]
async fn test_static_save_load(){
let path = PathBuf::from("test1");
let test_path = TestPath::from(path.clone());
let a = A;
a.save(&test_path).unwrap();
let b = A::load(&test_path).unwrap();
assert_eq!(a,b);

tokio::fs::remove_dir_all(path).await.unwrap();
}

#[derive(Serialize,Deserialize,Save,Load,PartialEq,Debug)]
#[base_on(TestPath)]
struct B;

impl ExpandStorePoint for B{
fn get_suffix(&self) -> PathBuf {
PathBuf::from("test223.txt")
}
}

#[tokio::test]
async fn test_dynamic_save_load(){
let path = PathBuf::from("test2");
let test_path = TestPath::from(path.clone());
let b = B;
b.save(&test_path).unwrap();

let temp = B::load(&test_path,"test223.txt").unwrap();
assert_eq!(b,temp);

tokio::fs::remove_dir_all(path).await.unwrap();

}

#[derive(Serialize,Deserialize,PartialEq,Debug)]
struct C<T> where T:BaseStorePoint{
num:String,
_t:PhantomData<T>
}

impl <T> ExpandStorePoint for C<T> where T:BaseStorePoint{
fn get_suffix(&self) -> PathBuf {
PathBuf::from(&format!("{}.txt",&self.num))
}
}

impl <T> Save for C<T> where T:BaseStorePoint{
type AcceptStorePoint = T;
}

impl <T> Load for C<T> where T:BaseStorePoint{
type AcceptStorePoint = T;
}

type D = C<TestPath>;

impl From<String> for D{
fn from(value: String) -> Self {
Self{
num: value,
_t: Default::default(),
}
}
}

#[tokio::test]
async fn generic_test(){
let path = PathBuf::from("test3");
let test_path = TestPath::from(path.clone());
let d:D = String::from("123").into();
d.save(&test_path).unwrap();

let temp = D::load(&test_path,"123.txt").unwrap();
assert_eq!(d,temp);

tokio::fs::remove_dir_all(path).await.unwrap();
}


#[derive(Serialize,Deserialize,PartialEq,Debug,Save,Load)]
struct E<T> where T:BaseStorePoint{
num:String,
_t:PhantomData<T>
}

impl <T> ExpandStorePoint for E<T> where T:BaseStorePoint{
fn get_suffix(&self) -> PathBuf {
PathBuf::from(&format!("{}.txt",&self.num))
}
}


}
1 change: 1 addition & 0 deletions reginleif-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod expiring_data;
pub mod serde_convert;
pub mod save_path;
Loading

0 comments on commit 2c485e6

Please sign in to comment.