mirror of
https://github.com/kristoferssolo/traxor.git
synced 2025-10-21 20:10:35 +00:00
refactor(units): use derive macro
This commit is contained in:
parent
7d58d1b74c
commit
fe3ddf165e
250
derive_macro/Cargo.lock
generated
250
derive_macro/Cargo.lock
generated
@ -9,8 +9,49 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"trybuild",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
@ -29,6 +70,53 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.140"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.104"
|
||||
@ -40,8 +128,170 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-triple"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_write",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_write"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "trybuild"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c9bf9513a2f4aeef5fdac8677d7d349c79fdbcc03b9c86da6e9d254f1e43be2"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"target-triple",
|
||||
"termcolor",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@ -10,3 +10,6 @@ crate-type = ["proc-macro"]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "2.0", features = ["full", "extra-traits"] }
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
mod merge;
|
||||
mod unit;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{DeriveInput, parse_macro_input};
|
||||
@ -9,3 +10,8 @@ pub fn merge_derive(input: TokenStream) -> TokenStream {
|
||||
merge::impl_merge_derive(input)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(UnitConversions, attributes(units, error))]
|
||||
pub fn unit_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
unit::impl_unit_conversions(input)
|
||||
}
|
||||
|
||||
134
derive_macro/src/unit.rs
Normal file
134
derive_macro/src/unit.rs
Normal file
@ -0,0 +1,134 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{Attribute, DeriveInput, Error, Type, parse_quote};
|
||||
|
||||
pub fn impl_unit_conversions(input: DeriveInput) -> TokenStream {
|
||||
let name = &input.ident;
|
||||
|
||||
let mut unsigned_types = Vec::new();
|
||||
let mut signed_types = Vec::new();
|
||||
let mut error_type: Option<Type> = None;
|
||||
|
||||
for attr in &input.attrs {
|
||||
if attr.path().is_ident("units") {
|
||||
if let Ok(types) = parse_unit_types(attr) {
|
||||
for ty in types {
|
||||
let type_str = quote!(#ty).to_string();
|
||||
if is_signed_type(&type_str) {
|
||||
signed_types.push(ty);
|
||||
} else {
|
||||
unsigned_types.push(ty);
|
||||
}
|
||||
}
|
||||
} else if attr.path().is_ident("error") {
|
||||
if let Ok(err_type) = parse_error_types(attr) {
|
||||
error_type = Some(err_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if unsigned_types.is_empty() && signed_types.is_empty() {
|
||||
unsigned_types = vec![
|
||||
parse_quote!(u8),
|
||||
parse_quote!(u16),
|
||||
parse_quote!(u32),
|
||||
parse_quote!(u64),
|
||||
parse_quote!(usize),
|
||||
];
|
||||
signed_types = vec![
|
||||
parse_quote!(i8),
|
||||
parse_quote!(i16),
|
||||
parse_quote!(i32),
|
||||
parse_quote!(i64),
|
||||
parse_quote!(isize),
|
||||
];
|
||||
}
|
||||
|
||||
let error_type = error_type.unwrap_or_else(|| parse_quote!(String));
|
||||
let is_string_error = quote!(#error_type).to_string() == "String";
|
||||
|
||||
let from_impls = unsigned_types.iter().map(|ty| {
|
||||
let conversion_expr = if name == "Unit" {
|
||||
quote! { Self(value as u64) }
|
||||
} else {
|
||||
quote! { Self(crate::app::utils::unit::Unit::new(value as u64)) }
|
||||
};
|
||||
quote! {
|
||||
impl From<#ty> for #name {
|
||||
fn from(value: #ty) -> Self {
|
||||
#conversion_expr
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let try_from_impls = signed_types.iter().map(|ty| {
|
||||
let error_creation = if is_string_error {
|
||||
quote! {
|
||||
format!("Cannot convert negative value {} to {}", value, stringify!(#name))
|
||||
}
|
||||
} else {
|
||||
// For custom error types, try to construct from a string message
|
||||
// This assumes the error type implements From<String> or similar
|
||||
quote! {
|
||||
#error_type::from(format!("Cannot convert negative value {} to {}", value, stringify!(#name)))
|
||||
}
|
||||
};
|
||||
|
||||
let conversion_expr = if name == "Unit" {
|
||||
quote! { Ok(Self(value as u64)) }
|
||||
} else {
|
||||
quote! { Ok(Self(crate::app::utils::unit::Unit::try_from(value)?)) }
|
||||
};
|
||||
|
||||
quote! {
|
||||
impl TryFrom<#ty> for #name {
|
||||
type Error = #error_type;
|
||||
|
||||
fn try_from(value: #ty) -> Result<Self, Self::Error> {
|
||||
if value < 0 {
|
||||
return Err(#error_creation);
|
||||
}
|
||||
#conversion_expr
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let expanded = quote! {
|
||||
#(#from_impls)*
|
||||
#(#try_from_impls)*
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
fn parse_unit_types(attr: &Attribute) -> Result<Vec<Type>, Error> {
|
||||
let mut types = Vec::new();
|
||||
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if let Ok(ty) = meta.value()?.parse::<Type>() {
|
||||
types.push(ty);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(types)
|
||||
}
|
||||
|
||||
fn parse_error_types(attr: &Attribute) -> Result<Type, Error> {
|
||||
let mut error_type = None;
|
||||
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if let Ok(ty) = meta.value()?.parse::<Type>() {
|
||||
error_type = Some(ty);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
error_type.ok_or_else(|| Error::new_spanned(attr, "Expected error type"))
|
||||
}
|
||||
|
||||
fn is_signed_type(type_str: &str) -> bool {
|
||||
matches!(type_str, "i8" | "i16" | "i32" | "i64" | "isize")
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
use super::unit::{Unit, UnitError};
|
||||
use crate::app::utils::unit::UnitDisplay;
|
||||
use super::unit::{Unit, UnitDisplay};
|
||||
use derive_macro::UnitConversions;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default, UnitConversions)]
|
||||
#[error(UnitError)]
|
||||
pub struct FileSize(Unit);
|
||||
|
||||
impl FileSize {
|
||||
@ -17,35 +18,3 @@ impl Display for FileSize {
|
||||
write!(f, "{}", UnitDisplay::new(&self.0, UNITS))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_unsigned {
|
||||
($type:ty, $($t:ty), *) => {
|
||||
$(
|
||||
impl From<$t> for $type {
|
||||
fn from(value: $t) -> Self {
|
||||
Self(Unit::from(value))
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_try_from_signed {
|
||||
($type:ty, $error:ty, $($t:ty), *) => {
|
||||
$(
|
||||
impl TryFrom<$t> for $type {
|
||||
type Error = $error;
|
||||
|
||||
fn try_from(value: $t) -> Result<Self, Self::Error> {
|
||||
if value < 0 {
|
||||
return Err(UnitError::NegativeValue { value: value as i64 });
|
||||
}
|
||||
Ok(Self(Unit::try_from(value)?))
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_unsigned!(FileSize, u8, u16, u32, u64, usize);
|
||||
impl_try_from_signed!(FileSize, UnitError, i8, i16, i32, i64, isize);
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use super::unit::{Unit, UnitError};
|
||||
use crate::app::utils::unit::UnitDisplay;
|
||||
use super::unit::{Unit, UnitDisplay};
|
||||
use derive_macro::UnitConversions;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default, UnitConversions)]
|
||||
#[error(UnitError)]
|
||||
pub struct NetSpeed(Unit);
|
||||
|
||||
impl NetSpeed {
|
||||
@ -17,35 +18,3 @@ impl Display for NetSpeed {
|
||||
write!(f, "{}", UnitDisplay::new(&self.0, UNITS))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_unsigned {
|
||||
($type:ty, $($t:ty), *) => {
|
||||
$(
|
||||
impl From<$t> for $type {
|
||||
fn from(value: $t) -> Self {
|
||||
Self(Unit::from(value))
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_try_from_signed {
|
||||
($type:ty, $error:ty, $($t:ty), *) => {
|
||||
$(
|
||||
impl TryFrom<$t> for $type {
|
||||
type Error = $error;
|
||||
|
||||
fn try_from(value: $t) -> Result<Self, Self::Error> {
|
||||
if value < 0 {
|
||||
return Err(UnitError::NegativeValue { value: value as i64 });
|
||||
}
|
||||
Ok(Self(Unit::try_from(value)?))
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_unsigned!(NetSpeed, u8, u16, u32, u64, usize);
|
||||
impl_try_from_signed!(NetSpeed, UnitError, i8, i16, i32, i64, isize);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use derive_macro::UnitConversions;
|
||||
use std::fmt::Display;
|
||||
use thiserror::Error;
|
||||
|
||||
@ -11,7 +12,8 @@ pub enum UnitError {
|
||||
InvalidValue { reason: String },
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default, UnitConversions)]
|
||||
#[error(UnitError)]
|
||||
pub struct Unit(u64);
|
||||
|
||||
impl Unit {
|
||||
@ -24,6 +26,7 @@ impl Unit {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnitDisplay<'a> {
|
||||
unit: &'a Unit,
|
||||
units: &'a [&'a str],
|
||||
@ -55,35 +58,3 @@ impl<'a> Display for UnitDisplay<'a> {
|
||||
write!(f, "{:.2} {}", size, self.units[unit_index])
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_unsigned {
|
||||
($type:ty, $($t:ty), *) => {
|
||||
$(
|
||||
impl From<$t> for $type {
|
||||
fn from(value: $t) -> Self {
|
||||
Self(value as u64)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_try_from_signed {
|
||||
($type:ty, $error:ty, $($t:ty), *) => {
|
||||
$(
|
||||
impl TryFrom<$t> for $type {
|
||||
type Error = $error;
|
||||
|
||||
fn try_from(value: $t) -> Result<Self, Self::Error> {
|
||||
if value < 0 {
|
||||
return Err(UnitError::NegativeValue { value: value as i64 });
|
||||
}
|
||||
Ok(Self(value as u64))
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_unsigned!(Unit, u8, u16, u32, u64, usize);
|
||||
impl_try_from_signed!(Unit, UnitError, i8, i16, i32, i64, isize);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user