#![allow(
clippy::cognitive_complexity,
clippy::large_enum_variant,
clippy::module_inception,
clippy::needless_doctest_main
)]
#![warn(
missing_debug_implementations,
// missing_docs,
rust_2021_compatibility,
unreachable_pub
)]
#![deny(unused_must_use)]
#![doc(test(
no_crate_inject,
attr(
deny(warnings, rust_2021_compatibility),
allow(dead_code, unused_variables)
)
))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, allow(unused_attributes))]
#![cfg_attr(loom, allow(dead_code, unreachable_pub))]
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(Json)]
pub fn json_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let struct_name = &input.ident;
let expanded = quote! {
impl #struct_name {
pub fn self_json_cloned<T:serde::ser::Serialize>(&self, target:&T) -> Self{
Self::own_json_cloned(self,target)
}
pub fn auto_json_cloned<R:serde::de::DeserializeOwned,T:serde::ser::Serialize>(target:&T) -> R {
Self::own_json_cloned(&Self::default(),target)
}
fn own_json_cloned<R:serde::de::DeserializeOwned,S:serde::ser::Serialize,T:serde::ser::Serialize>(source:&S,target:&T) -> R {
let mut e_self:serde_json::Map<String, serde_json::Value> =
serde_json::from_str::<serde_json::Value>(&serde_json::to_string(source).unwrap())
.unwrap().as_object()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "Target is not an object"))
.unwrap()
.clone();
let e_target:serde_json::Map<String, serde_json::Value> =
serde_json::from_str::<serde_json::Value>(&serde_json::to_string(target).unwrap())
.unwrap().as_object()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "Target is not an object"))
.unwrap()
.clone();
for (k, v) in e_target {
e_self.insert(k, v);
}
serde_json::from_value(serde_json::Value::Object(e_self)).unwrap()
}
pub fn auto_write_json<P:AsRef<std::path::Path>,S:AsRef<str>>(&self, fpath: P, fname: S) -> std::io::Result<()> {
let fpath = fpath.as_ref();
let fname = fname.as_ref();
if !fpath.exists() {
std::fs::create_dir_all(fpath)?;
}
std::fs::write(fpath.join(fname), serde_json::to_string_pretty(self)?)?;
std::io::Result::Ok(())
}
pub fn auto_read_json<P:AsRef<std::path::Path>>(path: P) -> std::io::Result<Self> {
let path = path.as_ref();
std::io::Result::Ok(serde_json::from_str::<Self>(&std::fs::read_to_string(
path
)?)?)
}
pub fn to_s(&self) -> String{
serde_json::to_string_pretty(self).unwrap_or_default()
}
}
};
TokenStream::from(expanded)
}
#[proc_macro_derive(C)]
pub fn c_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let struct_name = &input.ident;
let expanded = quote! {
impl #struct_name {
pub fn to_c_ptr(self) -> *const std::ffi::c_void {
Box::into_raw(Box::new(self)) as *const std::ffi::c_void
}
pub unsafe fn from_c_ptr(void_ptr: *const std::ffi::c_void) -> Option<Box<Self>> {
let non_null_ptr = std::ptr::NonNull::new(void_ptr as *mut Self);
non_null_ptr.map(|ptr| Box::from_raw(ptr.as_ptr() as *mut Self))
}
pub unsafe fn from_c_ptr2(void_ptr: *const std::ffi::c_void) -> Self {
std::ptr::read(void_ptr as *const Self)
}
pub unsafe fn from_c_mut_ptr(void_ptr: *mut c_void) -> Option<Box<Self>> {
let non_null_ptr = std::ptr::NonNull::new(void_ptr as *mut Self);
non_null_ptr.map(|ptr| Box::from_raw(ptr.as_ptr() as *mut Self))
}
}
};
TokenStream::from(expanded)
}