Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions examples/Eq_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use tagged_core::Tagged;

fn main() {
}
#[test]
fn test_eq() {
let a = Tagged::<u32, String>::new(42);
let b = Tagged::<u32, String>::new(42);
let c = Tagged::<u32, String>::new(35);
let d = Tagged::<u32, String>::new(0);

assert!(a == b);
assert!(a > c);
assert!(a >= d);

}

#[test]
fn test_with_struct() {
use tagged_core::Tagged;

struct UserIdTag {
a: Tagged<u32, Self>,
b: Tagged<u32, Self>,
}


let instance = UserIdTag{a: 1.into(), b: 2.into()};

assert!(instance.a < instance.b);

// println!("{}", a);

}
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod rust_tagged{
pub use tagged_core::*;
}
// pub mod rust_tagged{
// pub use tagged_core::*;
// }

pub use tagged_core::*;
32 changes: 32 additions & 0 deletions tagged-core/examples/Eq_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use tagged_core::Tagged;
fn main() {}
#[test]
fn test_eq() {
let a = Tagged::<u32, String>::new(42);
let b = Tagged::<u32, String>::new(42);
let c = Tagged::<u32, String>::new(35);
let d = Tagged::<u32, String>::new(0);

assert!(a == b);
assert!(a > c);
assert!(a >= d);

}

#[test]
fn test_with_struct() {
use tagged_core::Tagged;

struct UserIdTag {
a: Tagged<u32, Self>,
b: Tagged<u32, Self>,
}


let instance = UserIdTag{a: 1.into(), b: 2.into()};

assert!(instance.a < instance.b);

// println!("{}", a);

}
49 changes: 35 additions & 14 deletions tagged-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cmp::Ordering;
use std::ops::Deref;
/// rust-tagged provides a simple way to define strongly typed wrappers over primitive types like String, i32, Uuid, chrono::DateTime, etc. It helps eliminate bugs caused by misusing raw primitives for conceptually distinct fields such as UserId, Email, ProductId, and more.
///
Expand All @@ -8,7 +9,7 @@ use std::ops::Deref;
/// # Example
///
/// ```
/// use rust_tagged::{Tagged};
/// use tagged_core::{Tagged};
///
/// #[derive(Debug)]
/// struct EmailTag;
Expand All @@ -24,12 +25,12 @@ use std::ops::Deref;
/// println!("Raw String: {raw}");
/// }
/// ```
pub struct Tagged<T, U> {
pub struct Tagged<T, Tag> {
value: T,
_marker: std::marker::PhantomData<U>,
_marker: std::marker::PhantomData<Tag>,
}

impl<T, U> Tagged<T, U> {
impl<T, Tag> Tagged<T, Tag> {
pub fn new(value: T) -> Self {
Self {
value,
Expand All @@ -43,41 +44,60 @@ impl<T, U> Tagged<T, U> {
}


/// Blanket `From<T>` for `Tagged<T, U>`
impl<T, U> From<T> for Tagged<T, U> {
/// Blanket `From<T>` for `Tagged<T, Tag>`
impl<T, Tag> From<T> for Tagged<T, Tag> {
fn from(value: T) -> Self {
Tagged::new(value)
}
}

/// Support `From<&str>` → `Tagged<String, U>`
impl<U> From<&str> for Tagged<String, U> {
/// Support `From<&str>` → `Tagged<String, Tag>`
impl<Tag> From<&str> for Tagged<String, Tag> {
fn from(s: &str) -> Self {
Tagged::new(s.to_string())
}
}

/// Support `From<&String>` → `Tagged<String, U>`
impl<U> From<&String> for Tagged<String, U> {
/// Support `From<&String>` → `Tagged<String, Tag>`
impl<Tag> From<&String> for Tagged<String, Tag> {
fn from(s: &String) -> Self {
Tagged::new(s.clone())
}
}

impl<T, U> Deref for Tagged<T, U> {
impl<T, Tag> Deref for Tagged<T, Tag> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T: PartialEq, Tag> PartialEq for Tagged<T, Tag> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}

impl<T: Eq, Tag> Eq for Tagged<T, Tag> {}

impl<T: PartialOrd, Tag> PartialOrd for Tagged<T, Tag> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.value.partial_cmp(&other.value)
}
}

impl<T: Ord, Tag> Ord for Tagged<T, Tag> {
fn cmp(&self, other: &Self) -> Ordering {
self.value.cmp(&other.value)
}
}

// For all common primitive types
// macro_rules! impl_from_tagged {
// ($($t:ty),*) => {
// $(
// impl<U> From<Tagged<$t, U>> for $t {
// fn from(tagged: Tagged<$t, U>) -> Self {
// impl<Tag> From<Tagged<$t, Tag>> for $t {
// fn from(tagged: Tagged<$t, Tag>) -> Self {
// tagged.value
// }
// }
Expand Down Expand Up @@ -111,4 +131,5 @@ mod tests {

assert_eq!(tagged_struct.id.value, 0);
}
}
}