Skip to content

Commit

Permalink
fix the import mess from within diman_unit_system by adding an intern…
Browse files Browse the repository at this point in the history
…al diman_unit_system macro and moving codegen to a Codegen struct (instead of defs)
  • Loading branch information
Tehforsch committed Jan 13, 2024
1 parent c0c6377 commit 822b133
Show file tree
Hide file tree
Showing 33 changed files with 200 additions and 213 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ The `unit_system!` macro also allows defining derived dimensions and units:
```rust ignore
#![allow(incomplete_features)]
#![feature(generic_const_exprs, adt_const_params)]
use diman_unit_system::unit_system;
use diman::unit_system;
unit_system!(
quantity_type Quantity;
dimension_type Dimension;
Expand Down
7 changes: 4 additions & 3 deletions crates/diman_unit_system/src/codegen/base_dimension_type.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use proc_macro2::{Ident, TokenStream};
use quote::quote;

use crate::types::{BaseDimensionExponent, Defs};
use super::Codegen;
use crate::types::BaseDimensionExponent;

#[cfg(feature = "rational-dimensions")]
impl Defs {
impl Codegen {
pub fn get_base_dimension_entry(
&self,
field: &Ident,
Expand Down Expand Up @@ -78,7 +79,7 @@ impl Defs {
}

#[cfg(not(feature = "rational-dimensions"))]
impl Defs {
impl Codegen {
pub fn get_base_dimension_entry(
&self,
field: &Ident,
Expand Down
16 changes: 8 additions & 8 deletions crates/diman_unit_system/src/codegen/debug_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ use quote::quote;

use crate::{
dimension_math::BaseDimensions,
types::{base_dimension::BaseDimension, Defs, Unit},
types::{base_dimension::BaseDimension, Unit},
};

impl Defs {
use super::Codegen;

impl Codegen {
pub fn units_array<'a>(&self, units: impl Iterator<Item = &'a Unit>) -> TokenStream {
let units: TokenStream = units
.filter_map(|unit| {
Expand All @@ -22,13 +24,11 @@ impl Defs {
}

pub fn gen_debug_trait_impl(&self) -> TokenStream {
let Defs {
quantity_type,
dimension_type,
..
} = &self;
let units = self.units_array(self.units.iter().filter(|unit| unit.magnitude == 1.0));
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
let units = self.units_array(self.defs.units.iter().filter(|unit| unit.magnitude == 1.0));
let get_base_dimension_symbols = self
.defs
.base_dimensions
.iter()
.map(|base_dim| self.get_base_dimension_symbol(base_dim))
Expand Down
30 changes: 22 additions & 8 deletions crates/diman_unit_system/src/codegen/dimension_type.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use proc_macro2::{Ident, TokenStream};
use quote::quote;

use crate::types::Defs;
use super::{CallerType, Codegen};

impl Defs {
impl Codegen {
pub(crate) fn gen_dimension(&self) -> TokenStream {
let name = &self.dimension_type;
let name = &self.defs.dimension_type;

let dim_type = self.base_dimension_type();
let dimensions: proc_macro2::TokenStream = self
.defs
.base_dimensions
.iter()
.map(|dim| {
Expand All @@ -19,8 +20,9 @@ impl Defs {
})
.collect();
let methods_impl: proc_macro2::TokenStream = self.dimension_methods_impl();
let use_ratio = self.use_ratio();
quote! {
use ::diman::Ratio;
#use_ratio

#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::clone::Clone, ::core::fmt::Debug, ::core::marker::ConstParamTy)]
pub struct #name {
Expand All @@ -31,11 +33,23 @@ impl Defs {
}
}

fn use_ratio(&self) -> TokenStream {
match self.caller_type {
CallerType::External => {
quote! { use ::diman::Ratio; }
}
CallerType::Internal => {
quote! { use ::diman_lib::ratio::Ratio; }
}
}
}

fn dimension_methods_impl(&self) -> TokenStream {
let type_name = &self.dimension_type;
let gen = |f: &dyn Fn(&Defs, &Ident) -> TokenStream| {
self.base_dimensions()
.map(|ident| f(self, ident))
let type_name = &self.defs.dimension_type;
let gen = |f: &dyn Fn(&Codegen, &Ident) -> TokenStream| {
self.defs
.base_dimensions()
.map(|ident| f(&self, ident))
.collect::<TokenStream>()
};
let none_gen = gen(&Self::zero_entry);
Expand Down
57 changes: 19 additions & 38 deletions crates/diman_unit_system/src/codegen/dimensions.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use crate::{dimension_math::BaseDimensions, types::Defs};
use crate::dimension_math::BaseDimensions;
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned};

use super::storage_types::StorageType;
use super::{storage_types::StorageType, Codegen};

impl Defs {
impl Codegen {
pub(crate) fn gen_quantity(&self) -> TokenStream {
let Self {
quantity_type,
dimension_type,
..
} = &self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
let span = quantity_type.span();
let functions = self.quantity_functions();
quote_spanned! {span =>
Expand All @@ -22,11 +19,8 @@ impl Defs {
}

fn quantity_functions(&self) -> TokenStream {
let Self {
quantity_type,
dimension_type,
..
} = &self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
quote! {
impl<S> #quantity_type<S, { #dimension_type::none() }> {
/// Get the value of a dimensionless quantity
Expand Down Expand Up @@ -67,13 +61,13 @@ impl Defs {
}

pub fn get_dimension_expr(&self, dim: &BaseDimensions) -> TokenStream {
let dimension_type = &self.dimension_type;
let dimension_type = &self.defs.dimension_type;
let field_updates: TokenStream = dim
.fields()
.map(|(field, value)| self.get_base_dimension_entry(field, value))
.collect();
let span = self.quantity_type.span();
let none_update = if dim.num_fields() < self.base_dimensions.len() {
let span = self.defs.quantity_type.span();
let none_update = if dim.num_fields() < self.defs.base_dimensions.len() {
quote! { ..#dimension_type::none() }
} else {
quote! {}
Expand All @@ -98,54 +92,41 @@ impl Defs {
.collect()
}

#[cfg(feature = "rational-dimensions")]
fn use_ratio(&self) -> TokenStream {
quote! { use super::Ratio; }
}

#[cfg(not(feature = "rational-dimensions"))]
fn use_ratio(&self) -> TokenStream {
quote! {}
}

fn definitions_for_storage_type(
&self,
type_: &dyn StorageType,
module_name: &TokenStream,
gen_constants: bool,
) -> TokenStream {
let Self {
dimension_type,
quantity_type,
..
} = &self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
let quantities = self.quantity_definitions_for_storage_type(type_);
let constants = if gen_constants {
self.constant_definitions_for_storage_type(type_)
} else {
quote! {}
};
let use_ratio = self.use_ratio();
quote! {
pub mod #module_name {
use super::#dimension_type;
use super::#quantity_type;
#use_ratio
use super::Ratio;
#quantities
#constants
}
}
}

fn quantity_definitions_for_storage_type(&self, type_: &dyn StorageType) -> TokenStream {
self.dimensions
self.defs
.dimensions
.iter()
.map(|quantity| {
let dimension = self.get_dimension_expr(&quantity.dimensions);
let quantity_type = &self.quantity_type;
let quantity_type = &self.defs.quantity_type;
let quantity_name = &quantity.name;
let type_ = type_.name();
let span = self.dimension_type.span();
let span = self.defs.dimension_type.span();
quote_spanned! {span =>
pub type #quantity_name = #quantity_type::<#type_, { #dimension }>;
}
Expand All @@ -155,11 +136,11 @@ impl Defs {

fn constant_definitions_for_storage_type(&self, type_: &dyn StorageType) -> TokenStream {
self
.constants
.defs.constants
.iter()
.map(|constant| {
let dimension = self.get_dimension_expr(&constant.dimensions);
let quantity_type = &self.quantity_type;
let quantity_type = &self.defs.quantity_type;
let constant_name = &constant.name;
let value = constant.magnitude;
let float_type = &type_.base_storage().name;
Expand Down
20 changes: 6 additions & 14 deletions crates/diman_unit_system/src/codegen/float_methods.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use proc_macro2::TokenStream;
use quote::quote;

use crate::types::Defs;
use super::{join, storage_types::FloatType, Codegen};

use super::{join, storage_types::FloatType};

impl Defs {
impl Codegen {
fn ensure_float_traits(&self) -> TokenStream {
if cfg!(feature = "num-traits-libm") {
quote! {
Expand All @@ -24,11 +22,8 @@ impl Defs {
method_name: &TokenStream,
) -> TokenStream {
let float_type_name = &float_type.name;
let Self {
dimension_type,
quantity_type,
..
} = &self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
quote! {
impl #quantity_type<#float_type_name, {#dimension_type::none()} > {
pub fn #method_name(&self) -> #quantity_type<#float_type_name, {#dimension_type::none()}> {
Expand Down Expand Up @@ -96,11 +91,8 @@ impl Defs {

fn specific_float_methods(&self, float_type: &FloatType) -> TokenStream {
let float_type = &float_type.name;
let Self {
dimension_type,
quantity_type,
..
} = &self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
quote! {
impl<const D: #dimension_type> #quantity_type<#float_type, D> {
pub fn squared(&self) -> #quantity_type<#float_type, { D.mul(2) }>
Expand Down
11 changes: 4 additions & 7 deletions crates/diman_unit_system/src/codegen/generic_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use proc_macro2::TokenStream;
use quote::quote;
use syn::Type;

use crate::types::Defs;
use super::Codegen;

impl Defs {
impl Codegen {
pub fn gen_generic_methods(&self) -> TokenStream {
self.storage_type_names()
.map(|name| self.impl_method_for_generic_storage_type(&name, &quote! { abs }))
Expand All @@ -16,11 +16,8 @@ impl Defs {
storage_type: &Type,
name: &TokenStream,
) -> TokenStream {
let Self {
dimension_type,
quantity_type,
..
} = &self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
quote! {
impl<const D: #dimension_type> #quantity_type<#storage_type, D> {
pub fn #name(&self) -> #quantity_type<#storage_type, D> {
Expand Down
17 changes: 6 additions & 11 deletions crates/diman_unit_system/src/codegen/hdf5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ use quote::quote;

use super::join;
use super::storage_types::{FloatType, VectorType};
use super::Codegen;
use crate::types::Defs;

impl Defs {
impl Codegen {
pub fn gen_hdf5_impl(&self) -> TokenStream {
join([self.hdf5_floats_impl(), self.hdf5_vectors_impl()])
}
Expand All @@ -20,11 +21,8 @@ impl Defs {
fn hdf5_float_impl(&self, float_type: &FloatType) -> TokenStream {
let float_type_name = &float_type.name;
let hdf5_type = &float_type.hdf5_type;
let Defs {
dimension_type,
quantity_type,
..
} = self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
quote! {
unsafe impl<const D: #dimension_type> hdf5::H5Type for #quantity_type<#float_type_name, D> {
fn type_descriptor() -> hdf5::types::TypeDescriptor {
Expand All @@ -45,11 +43,8 @@ impl Defs {
let vector_type_name = &vector_type.name;
let hdf5_type = &vector_type.float_type.hdf5_type;
let num_dims = vector_type.num_dims;
let Defs {
dimension_type,
quantity_type,
..
} = self;
let dimension_type = &self.defs.dimension_type;
let quantity_type = &self.defs.quantity_type;
quote! {
unsafe impl<const D: #dimension_type> hdf5::H5Type for #quantity_type<#vector_type_name, D> {
fn type_descriptor() -> hdf5::types::TypeDescriptor {
Expand Down
17 changes: 16 additions & 1 deletion crates/diman_unit_system/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,26 @@ use proc_macro2::TokenStream;

use crate::types::Defs;

pub enum CallerType {
/// The macro is called from within this crate (`diman_unit_system`)
/// and imports need to be directly from `diman_lib`.
#[allow(dead_code)]
Internal,
/// The macro is called from somewhere else (`diman` or a user's crate)
/// and imports need to be from `diman`.
External,
}

pub struct Codegen {
pub defs: Defs,
pub caller_type: CallerType,
}

fn join<const D: usize>(streams: [TokenStream; D]) -> TokenStream {
streams.into_iter().collect()
}

impl Defs {
impl Codegen {
pub fn code_gen(&self) -> TokenStream {
join([
self.gen_dimension(),
Expand Down
Loading

0 comments on commit 822b133

Please sign in to comment.