Skip to content

Commit

Permalink
refactor: move public to a separate crate
Browse files Browse the repository at this point in the history
  • Loading branch information
vnghia committed Apr 8, 2024
1 parent 9ba8880 commit 8b500fd
Show file tree
Hide file tree
Showing 89 changed files with 1,128 additions and 820 deletions.
21 changes: 20 additions & 1 deletion Cargo.lock

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

52 changes: 35 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["frontend", "proc_macros"]
members = ["frontend", "proc_macros", "types"]

[workspace.package]
version = "0.1.0"
Expand All @@ -10,15 +10,31 @@ name = "nghe"
version.workspace = true
edition.workspace = true

[workspace.dependencies]
concat-string = "1.0.1"
derivative = "2.2.0"
fake = { version = "2.9.2", features = [
"derive",
"uuid",
"serde_json",
"time",
] }
isolang = { version = "2.4.0", default-features = false, features = ["serde"] }
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.115"
serde_with = { version = "3.7.0", features = ["hex"] }
strum = { version = "0.26.2", features = ["derive"] }
time = { version = "0.3.34", features = ["serde-human-readable", "macros"] }
uuid = { version = "1.8.0", features = ["v4", "serde"] }

[dependencies]
anyhow = { version = "1.0.81", features = ["backtrace"] }
async-trait = "0.1.79"
axum = { version = "0.7.5", features = ["http2", "macros"] }
axum-extra = { version = "0.9.3", features = ["form"] }
concat-string = "1.0.1"
concat-string.workspace = true
constcat = "0.5.0"
derivative = "2.2.0"
derive-new = "0.6.0"
derivative.workspace = true
diesel = { version = "2.1.5", features = ["uuid", "time"] }
diesel-async = { version = "0.4.1", features = [
"postgres",
Expand All @@ -32,7 +48,7 @@ futures = "0.3.30"
futures-buffered = "0.2.4"
hex = "0.4.3"
ignore = "0.4.22"
isolang = { version = "2.4.0", default-features = false, features = ["serde"] }
isolang.workspace = true
itertools = "0.12.1"
libaes = "0.7.0"
lofty = "0.18.2"
Expand All @@ -41,17 +57,20 @@ md5 = "0.7.0"
mimalloc = "0.1.39"
mime_guess = "2.0.4"
nghe-proc_macros = { path = "proc_macros" }
nghe-types = { path = "types", default-features = false, features = [
"backend",
] }
paste = "1.0.14"
rand = "0.8.5"
rayon = "1.10.0"
rsmpeg = { git = "https://github.com/vnghia/rsmpeg.git", rev = "e34a83a", features = [
"link_system_ffmpeg",
] }
serde = { version = "1.0", features = ["derive"] }
serde_with = { version = "3.7.0", features = ["hex"] }
strum = { version = "0.26.2", features = ["derive"] }
serde.workspace = true
serde_with.workspace = true
strum.workspace = true
thiserror = "1.0.58"
time = { version = "0.3.34", features = ["serde-human-readable", "macros"] }
time.workspace = true
tokio = { version = "1.37", features = ["full"] }
tokio-postgres = "0.7.10"
tokio-util = { version = "0.7.10", features = ["io"] }
Expand All @@ -60,26 +79,25 @@ tower-http = { version = "0.5.2", features = ["cors", "fs", "trace"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
urlencoding = "2.1.3"
uuid = { version = "1.8.0", features = ["v4", "serde"] }
uuid.workspace = true
walkdir = "2.5.0"
xxhash-rust = { version = "0.8.10", features = ["xxh3"] }

[build-dependencies]
built = { version = "0.7", features = ["git2"] }

[dev-dependencies]
fake = { version = "2.9.2", features = [
"derive",
"uuid",
"serde_json",
"time",
] }
fake.workspace = true
http-body-util = "0.1.1"
image = { version = "0.25.1", default-features = false, features = [
"jpeg",
"png",
] }
serde_json = "1.0.115"
nghe-types = { path = "types", default-features = false, features = [
"backend",
"test",
] }
serde_json.workspace = true
tempfile = "3.10.1"
url = "2.5.0"
uuid = { version = "1.8.0", features = ["v4", "fast-rng"] }
Expand Down
142 changes: 110 additions & 32 deletions proc_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![deny(clippy::all)]
#![feature(let_chains)]
#![feature(try_blocks, yeet_expr)]
#![feature(proc_macro_span)]

use std::collections::HashSet;
use std::ops::{Deref, DerefMut};
use std::sync::OnceLock;
Expand Down Expand Up @@ -31,6 +33,30 @@ fn get_base_name(ident: &Ident, suffix: &str) -> Result<String, Error> {
})
.map(String::from)
}
fn get_caller_types_module() -> ExprPath {
parse_str::<ExprPath>(
&std::path::Path::new("nghe_types")
.join(
proc_macro::Span::call_site()
.source_file()
.path()
.with_extension("")
.strip_prefix("src")
.unwrap(),
)
.components()
.map(|c| {
if let std::path::Component::Normal(c) = c {
c.to_string_lossy()
} else {
unreachable!()
}
})
.collect::<Vec<_>>()
.join("::"),
)
.unwrap()
}

#[derive(deluxe::ParseMetaItem)]
struct AddSubsonicResponse {
Expand Down Expand Up @@ -58,31 +84,29 @@ pub fn add_subsonic_response(
let subsonic_ident = format_ident!("Subsonic{}", item_ident.to_string());

quote! {
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
#[nghe_proc_macros::add_response_derive]
#item_struct

#[derive(serde::Serialize)]
#[nghe_proc_macros::add_response_derive]
pub struct #root_ident {
#[serde(flatten)]
constant: #constant_type,
pub constant: #constant_type,
#[serde(flatten)]
body: #item_ident,
pub body: #item_ident,
}

#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
#[nghe_proc_macros::add_response_derive]
pub struct #subsonic_ident {
#[serde(rename = "subsonic-response")]
root: #root_ident
pub root: #root_ident
}

impl From<#item_ident> for #subsonic_ident {
fn from(old: #item_ident) -> Self {
fn from(body: #item_ident) -> Self {
Self {
root: #root_ident {
constant: Default::default(),
body: old,
body,
}
}
}
Expand All @@ -98,6 +122,8 @@ pub fn add_subsonic_response(
#[proc_macro]
pub fn add_axum_response(item_ident: proc_macro::TokenStream) -> proc_macro::TokenStream {
match try {
let types_path = get_caller_types_module();

let item_ident = format_ident!("{}", item_ident.to_string());
let subsonic_ident = format_ident!("Subsonic{}", item_ident.to_string());

Expand All @@ -109,13 +135,9 @@ pub fn add_axum_response(item_ident: proc_macro::TokenStream) -> proc_macro::Tok
let json_response_ident = format_ident!("{}JsonResponse", base_type);

quote! {
pub type #json_response_ident = #json_response_path<#subsonic_ident>;
use #types_path::*;

impl From<#item_ident> for #json_response_ident {
fn from(value: #item_ident) -> Self {
Ok(axum::Json(value.into()))
}
}
pub type #json_response_ident = #json_response_path<#subsonic_ident>;
}
.into()
} {
Expand Down Expand Up @@ -208,12 +230,10 @@ pub fn add_common_convert(
common_params_fields.push(quote! { common, });

quote! {
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
#[nghe_proc_macros::add_request_derive]
#item_struct

#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
#[nghe_proc_macros::add_request_derive]
#common_item_struct

impl AsRef<#common_path> for #common_item_ident {
Expand Down Expand Up @@ -256,6 +276,8 @@ struct AddCommonValidate {
#[proc_macro]
pub fn add_common_validate(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
match try {
let types_path = get_caller_types_module();

let mut args = deluxe::parse2::<AddCommonValidate>(input.into())?
.args
.into_iter()
Expand Down Expand Up @@ -287,7 +309,7 @@ pub fn add_common_validate(input: proc_macro::TokenStream) -> proc_macro::TokenS
quote! { #role_name: #has_role }
})
.collect::<Vec<_>>();
let role_struct_path = parse_str::<ExprPath>("crate::models::users::Role")?;
let role_struct_path = parse_str::<ExprPath>("nghe_types::open_subsonic::user::Role")?;
let role_struct = quote! {
#role_struct_path {
#( #role_stmts ),*
Expand All @@ -305,14 +327,16 @@ pub fn add_common_validate(input: proc_macro::TokenStream) -> proc_macro::TokenS
let common_item_ident = format_ident!("{}WithCommon", base_type);

quote! {
use #types_path::*;

pub type #request_ident =
#validated_form_path<#common_item_ident, #item_ident,{ #role_struct }>;
#validated_form_path<#common_item_ident, #item_ident, { #role_struct }>;

#[cfg(test)]
impl #item_ident {
fn validated(self, user_id: uuid::Uuid) -> #request_ident {
#request_ident {
params: self,
impl #request_ident {
fn validated(params: #item_ident, user_id: uuid::Uuid) -> Self {
Self {
params,
user_id,
phantom: std::marker::PhantomData,
}
Expand All @@ -326,6 +350,60 @@ pub fn add_common_validate(input: proc_macro::TokenStream) -> proc_macro::TokenS
}
}

#[proc_macro_attribute]
pub fn add_request_derive(
_: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
match try {
let input: proc_macro2::TokenStream = input.into();
quote! {
#[cfg_attr(feature = "frontend", derive(serde::Serialize))]
#[cfg_attr(feature = "backend", derive(serde::Deserialize))]
#[cfg_attr(
all(test, not(any(feature = "frontend", feature = "backend"))),
derive(serde::Deserialize))
]
#[cfg_attr(
any(test, feature = "frontend", feature = "backend"),
serde(rename_all = "camelCase")
)]
#input
}
.into()
} {
Ok(r) => r,
Err::<_, Error>(e) => e.into_compile_error().into(),
}
}

#[proc_macro_attribute]
pub fn add_response_derive(
_: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
match try {
let input: proc_macro2::TokenStream = input.into();
quote! {
#[cfg_attr(feature = "frontend", derive(serde::Deserialize))]
#[cfg_attr(feature = "backend", derive(serde::Serialize))]
#[cfg_attr(
all(test, not(any(feature = "frontend", feature = "backend"))),
derive(serde::Serialize))
]
#[cfg_attr(
any(test, feature = "frontend", feature = "backend"),
serde(rename_all = "camelCase")
)]
#input
}
.into()
} {
Ok(r) => r,
Err::<_, Error>(e) => e.into_compile_error().into(),
}
}

fn modify_head_call_expr<F>(expr: &mut Expr, new_head_call: F) -> Result<(), Error>
where
F: Fn(&ExprCall) -> Expr,
Expand Down Expand Up @@ -484,12 +562,12 @@ pub fn generate_date_db(table_name: proc_macro::TokenStream) -> proc_macro::Toke
}
}

impl From<#date_type> for crate::open_subsonic::DateId3 {
fn from(value: #date_type) -> Self {
Self {
year: value.year.map(|v| v as _),
month: value.month.map(|v| v as _),
day: value.day.map(|v| v as _),
impl Into<nghe_types::open_subsonic::DateId3> for #date_type {
fn into(self) -> nghe_types::open_subsonic::DateId3 {
nghe_types::open_subsonic::DateId3 {
year: self.year.map(|v| v as _),
month: self.month.map(|v| v as _),
day: self.day.map(|v| v as _),
}
}
}
Expand Down
Loading

0 comments on commit 8b500fd

Please sign in to comment.