Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix serde impl and debug impl #71

Merged
merged 10 commits into from
Jan 16, 2024
2 changes: 0 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install mpich
- name: Run clippy on all targets
run: cargo clippy --version
- name: Run clippy on all targets
run: cargo clippy --all-targets --all-features -- -D warnings

Expand Down
26 changes: 26 additions & 0 deletions crates/diman_lib/src/dimension_exponent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::ops::{AddAssign, Mul, Neg};

pub trait DimensionExponent: Clone + PartialEq + Copy + Mul + AddAssign + Neg {
fn float_pow(num: f64, exponent: Self) -> f64;
fn one() -> Self;
fn zero() -> Self;
fn from_int(i: i32) -> Self;
}

impl DimensionExponent for i64 {
fn one() -> Self {
1
}

fn zero() -> Self {
0
}

fn float_pow(num: f64, exponent: Self) -> f64 {
num.powi(exponent as i32)
}

fn from_int(i: i32) -> Self {
i as i64
}
}
2 changes: 2 additions & 0 deletions crates/diman_lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#![allow(incomplete_features)]
#![feature(generic_const_exprs, adt_const_params)]

pub mod dimension_exponent;
pub mod ratio;
pub mod runtime_unit_storage;
26 changes: 17 additions & 9 deletions crates/diman_lib/src/ratio.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::dimension_exponent::DimensionExponent;

#[derive(
::core::cmp::PartialEq,
::core::cmp::Eq,
Expand All @@ -21,14 +23,6 @@ const fn gcd(mut a: i64, mut b: i64) -> i64 {
}

impl Ratio {
pub fn one() -> Self {
Self { num: 1, denom: 1 }
}

pub fn zero() -> Self {
Self { num: 0, denom: 1 }
}

pub const fn int(num: i64) -> Self {
Self { num, denom: 1 }
}
Expand Down Expand Up @@ -88,10 +82,24 @@ impl Ratio {
denom: self.num,
}
}
}

impl DimensionExponent for Ratio {
fn one() -> Self {
Self { num: 1, denom: 1 }
}

fn zero() -> Self {
Self { num: 0, denom: 1 }
}

pub fn float_pow(num: f64, exponent: Self) -> f64 {
fn float_pow(num: f64, exponent: Self) -> f64 {
num.powf(exponent.num as f64 / exponent.denom as f64)
}

fn from_int(i: i32) -> Self {
Ratio::int(i as i64)
}
}

impl core::fmt::Display for Ratio {
Expand Down
33 changes: 33 additions & 0 deletions crates/diman_lib/src/runtime_unit_storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
pub struct RuntimeUnit<'a, D> {
pub symbol: &'a str,
pub dimension: D,
pub magnitude: f64,
}

impl<'a, D> RuntimeUnit<'a, D> {
pub fn new(symbol: &'a str, dimension: D, magnitude: f64) -> Self {
Self {
symbol,
dimension,
magnitude,
}
}
}

pub struct RuntimeUnitStorage<'a, D> {
units: &'a [RuntimeUnit<'a, D>],
}

impl<'a, D: PartialEq> RuntimeUnitStorage<'a, D> {
pub fn new(units: &'a [RuntimeUnit<'a, D>]) -> Self {
Self { units }
}

pub fn get_first_unit_for_dimension(&self, dim: D) -> Option<&'a RuntimeUnit<'a, D>> {
self.units.iter().find(|unit| unit.dimension == dim)
}

pub fn get_unit_by_symbol(&self, symbol: &str) -> Option<&'a RuntimeUnit<'a, D>> {
self.units.iter().find(|unit| unit.symbol == symbol)
}
}
160 changes: 0 additions & 160 deletions crates/diman_unit_system/src/codegen/base_dimension_type.rs

This file was deleted.

52 changes: 30 additions & 22 deletions crates/diman_unit_system/src/codegen/debug_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,63 @@ use proc_macro2::TokenStream;
use quote::quote;

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

use super::Codegen;

impl Codegen {
pub fn units_array<'a>(&self, units: impl Iterator<Item = &'a Unit>) -> TokenStream {
pub fn runtime_unit_storage<'a>(&self, units: impl Iterator<Item = &'a Unit>) -> TokenStream {
let runtime_unit_storage = match self.caller_type {
CallerType::Internal => quote! { diman_lib::runtime_unit_storage::RuntimeUnitStorage },
CallerType::External => {
quote! { ::diman::internal::runtime_unit_storage::RuntimeUnitStorage }
}
};
let runtime_unit = match self.caller_type {
CallerType::Internal => quote! { diman_lib::runtime_unit_storage::RuntimeUnit },
CallerType::External => quote! { ::diman::internal::runtime_unit_storage::RuntimeUnit },
};
let units: TokenStream = units
.filter_map(|unit| {
let dim = self.get_dimension_expr(&unit.dimensions);
let magnitude = unit.magnitude;
let symbol = &unit.symbol.as_ref()?.0.to_string();
Some(quote! {
(#dim, #symbol, #magnitude),
#runtime_unit::new(
#symbol,
#dim,
#magnitude,
),
})
})
.collect();
quote! { [ #units ] }
quote! {
let units_array = &[#units];
let units = #runtime_unit_storage::new(units_array);
}
}

pub fn gen_debug_trait_impl(&self) -> TokenStream {
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 units_storage =
self.runtime_unit_storage(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))
.collect::<TokenStream>();
quote! {
fn get_symbol<const D: #dimension_type>() -> Option<&'static str> {
let units: &[(#dimension_type, &str, f64)] = &#units;
units
.iter()
.filter(|(d, name, _)| d == &D )
.map(|(_, name, _)| name)
.next()
.copied()
}

impl<const D: #dimension_type, S: core::fmt::Display> core::fmt::Debug for #quantity_type<S, D> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
#units_storage
self.0.fmt(f)?;
if let Some(symbol) = get_symbol::<D>() {
write!(f, " {}", symbol)
if let Some(unit) = units.get_first_unit_for_dimension(D) {
write!(f, " {}", unit.symbol)
}
else {
#get_base_dimension_symbols
Expand All @@ -62,15 +72,13 @@ impl Codegen {
fn get_base_dimension_symbol(&self, base_dim: &BaseDimension) -> TokenStream {
let dim = self.get_dimension_expr(&BaseDimensions::for_base_dimension(base_dim.clone()));
// We know that symbols exist for base dimensions, so we can unwrap here.
let base_dimension_type_zero = self.base_dimension_type_zero();
let base_dimension_type_one = self.base_dimension_type_one();
let base_dim = &base_dim.0;
quote! {
if D.#base_dim == #base_dimension_type_one {
write!(f, " {}", get_symbol::< { #dim }>().unwrap())?;
if D.#base_dim == Exponent::one() {
write!(f, " {}", units.get_first_unit_for_dimension(#dim).unwrap().symbol)?;
}
else if D.#base_dim != #base_dimension_type_zero {
write!(f, " {}^{}", get_symbol::< { #dim }>().unwrap(), D.#base_dim)?;
else if D.#base_dim != Exponent::zero() {
write!(f, " {}^{}", units.get_first_unit_for_dimension(#dim).unwrap().symbol, D.#base_dim)?;
}
}
}
Expand Down
Loading