pub struct Tagged<T, Tag> { /* private fields */ }Expand description
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.
Eliminate accidental mixups between similar types (e.g. OrgId vs UserId) Enforce domain modeling in code via the type system Ergonomic .into() support for primitive conversions
§Example - Simple
use tagged_core::{Tagged};
#[derive(Debug)]
struct EmailTag;
type Email = Tagged<String, EmailTag>;
fn main() {
let email: Email = "test@example.com".into();
println!("Email inner value: {}", email.value());
// Convert back to String
let raw: String = email.into();
println!("Raw String: {raw}");
}Implementations§
Trait Implementations§
Source§impl<T, Tag> Debug for Tagged<T, Tag>where
T: Debug,
§Example - Debug
use tagged_core::Tagged;
#[derive(Debug)]
struct UserIdTag {
a: Tagged<u32, Self>,
b: Tagged<u32, Self>,
}
fn main() {
let instance = UserIdTag{a: 1.into(), b: 2.into()};
println!("{}", instance.a);
println!("{:?}", instance.b);
}
impl<T, Tag> Debug for Tagged<T, Tag>where
T: Debug,
§Example - Debug
use tagged_core::Tagged;
#[derive(Debug)]
struct UserIdTag {
a: Tagged<u32, Self>,
b: Tagged<u32, Self>,
}
fn main() {
let instance = UserIdTag{a: 1.into(), b: 2.into()};
println!("{}", instance.a);
println!("{:?}", instance.b);
}Source§impl<'de, T, Tag> Deserialize<'de> for Tagged<T, Tag>where
T: Deserialize<'de>,
Available on crate feature serde only.
use serde::{Deserialize, Serialize};
use tagged_core::Tagged;
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct SomeCustomType {
some_id: String
}
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct SomeCustomType2(String);
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct User {
id: Tagged<String, Self>,
id2: SomeCustomType,
id3: SomeCustomType2,
}
fn main() {
let user = User { id: "1".into() , id2: SomeCustomType { some_id: "2".into() }, id3: SomeCustomType2("3".into())};
let j = serde_json::to_string(&user).unwrap();
let converted_user = serde_json::from_str::<User>(&j).unwrap();
println!("{}", j);
println!("{:?}", converted_user);
}
/*
Running `target/debug/examples/Serde_example`
{"id":"1","id2":{"some_id":"2"},"id3":"3"}
User { id: "1", id2: SomeCustomType { some_id: "2" }, id3: SomeCustomType2("3") }
Process finished with exit code 0
*/
/*
Problem with normal types
{"id":"1","id2":{"some_id":"2"}}
// rust is powerful enough to solve it using touple
{"id":"1","id2":{"some_id":"2"},"id3":"3"}
// or we can use a new type called tagged that don't need a new name.
*/
impl<'de, T, Tag> Deserialize<'de> for Tagged<T, Tag>where
T: Deserialize<'de>,
Available on crate feature
serde only.use serde::{Deserialize, Serialize};
use tagged_core::Tagged;
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct SomeCustomType {
some_id: String
}
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct SomeCustomType2(String);
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct User {
id: Tagged<String, Self>,
id2: SomeCustomType,
id3: SomeCustomType2,
}
fn main() {
let user = User { id: "1".into() , id2: SomeCustomType { some_id: "2".into() }, id3: SomeCustomType2("3".into())};
let j = serde_json::to_string(&user).unwrap();
let converted_user = serde_json::from_str::<User>(&j).unwrap();
println!("{}", j);
println!("{:?}", converted_user);
}
/*
Running `target/debug/examples/Serde_example`
{"id":"1","id2":{"some_id":"2"},"id3":"3"}
User { id: "1", id2: SomeCustomType { some_id: "2" }, id3: SomeCustomType2("3") }
Process finished with exit code 0
*/
/*
Problem with normal types
{"id":"1","id2":{"some_id":"2"}}
// rust is powerful enough to solve it using touple
{"id":"1","id2":{"some_id":"2"},"id3":"3"}
// or we can use a new type called tagged that don't need a new name.
*/Source§fn deserialize<D>(
deserializer: D,
) -> Result<Tagged<T, Tag>, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn deserialize<D>(
deserializer: D,
) -> Result<Tagged<T, Tag>, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
Source§impl<T, Tag> Hash for Tagged<T, Tag>where
T: Hash,
§Example - Hash
fn main() {
use tagged_core::Tagged;
use std::collections::HashSet;
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
struct User {
id: Tagged<String, Self>
}
let mut s: HashSet<User> = HashSet::new();
let user = User{id: "me@example.com".into()};
s.insert(user.clone());
assert!(s.contains(&user));
}
impl<T, Tag> Hash for Tagged<T, Tag>where
T: Hash,
§Example - Hash
fn main() {
use tagged_core::Tagged;
use std::collections::HashSet;
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
struct User {
id: Tagged<String, Self>
}
let mut s: HashSet<User> = HashSet::new();
let user = User{id: "me@example.com".into()};
s.insert(user.clone());
assert!(s.contains(&user));
}Source§impl<'a, T, Tag> IntoIterator for &'a Tagged<Vec<T>, Tag>
use tagged_core::Tagged;
#[derive(Debug)]
struct Org;
type EmployeeNames = Tagged<Vec<String>, Org>;
fn main() {
let names: EmployeeNames = Tagged::new(vec!["Alice".into(), "Bob".into()]);
names.iter().for_each(|name| println!("Name: {}", name));
}
/*
Name: Alice
Name: Bob
*/
impl<'a, T, Tag> IntoIterator for &'a Tagged<Vec<T>, Tag>
use tagged_core::Tagged;
#[derive(Debug)]
struct Org;
type EmployeeNames = Tagged<Vec<String>, Org>;
fn main() {
let names: EmployeeNames = Tagged::new(vec!["Alice".into(), "Bob".into()]);
names.iter().for_each(|name| println!("Name: {}", name));
}
/*
Name: Alice
Name: Bob
*/Source§impl<T, Tag> IntoIterator for Tagged<Vec<T>, Tag>
use tagged_core::Tagged;
#[derive(Debug)]
struct Org;
type EmployeeNames = Tagged<Vec<String>, Org>;
fn main() {
let names: EmployeeNames = Tagged::new(vec!["Alice".into(), "Bob".into()]);
names.into_iter().for_each(|name| println!("Name: {}", name));
}
/*
Name: Alice
Name: Bob
*/
impl<T, Tag> IntoIterator for Tagged<Vec<T>, Tag>
use tagged_core::Tagged;
#[derive(Debug)]
struct Org;
type EmployeeNames = Tagged<Vec<String>, Org>;
fn main() {
let names: EmployeeNames = Tagged::new(vec!["Alice".into(), "Bob".into()]);
names.into_iter().for_each(|name| println!("Name: {}", name));
}
/*
Name: Alice
Name: Bob
*/Source§impl<T, Tag> Ord for Tagged<T, Tag>where
T: Ord,
impl<T, Tag> Ord for Tagged<T, Tag>where
T: Ord,
1.21.0 · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Compares and returns the maximum of two values. Read more
Source§impl<T, Tag> PartialOrd for Tagged<T, Tag>where
T: PartialOrd,
impl<T, Tag> PartialOrd for Tagged<T, Tag>where
T: PartialOrd,
Source§impl<T, Tag> Serialize for Tagged<T, Tag>where
T: Serialize,
Available on crate feature serde only.Example - Serialize
impl<T, Tag> Serialize for Tagged<T, Tag>where
T: Serialize,
Available on crate feature
serde only.Example - Serialize
use serde::{Deserialize, Serialize};
use tagged_core::Tagged;
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct SomeCustomType {
some_id: String
}
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct SomeCustomType2(String);
#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct User {
id: Tagged<String, Self>,
id2: SomeCustomType,
id3: SomeCustomType2,
}
fn main() {
let user = User { id: "1".into() , id2: SomeCustomType { some_id: "2".into() }, id3: SomeCustomType2("3".into())};
let j = serde_json::to_string(&user).unwrap();
println!("{}", j);
}
/*
Problem with normal types
{"id":"1","id2":{"some_id":"2"}}
// rust is powerful enough to solve it using touple
{"id":"1","id2":{"some_id":"2"},"id3":"3"}
// or we can use a new type called tagged that don't need a new name.
*/Source§fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
Serialize this value into the given Serde serializer. Read more
impl<T, Tag> Eq for Tagged<T, Tag>where
T: Eq,
Auto Trait Implementations§
impl<T, Tag> Freeze for Tagged<T, Tag>where
T: Freeze,
impl<T, Tag> RefUnwindSafe for Tagged<T, Tag>where
T: RefUnwindSafe,
Tag: RefUnwindSafe,
impl<T, Tag> Send for Tagged<T, Tag>
impl<T, Tag> Sync for Tagged<T, Tag>
impl<T, Tag> Unpin for Tagged<T, Tag>
impl<T, Tag> UnwindSafe for Tagged<T, Tag>where
T: UnwindSafe,
Tag: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more