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
7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rust-tagged"
version = "0.4.0"
version = "0.5.0"
edition = "2024"
authors = ["Codefonsi <info@codefonsi.com>"]
license = "MPL-2.0"
Expand All @@ -18,17 +18,16 @@ include = ["src/**/*", "Cargo.toml", "../../README.md", "LICENSE"]
resolver = "3" # or "3"
members = [
"tagged-core",
"tagged-macros",
]

[patch.crates-io]
tagged-core = { path = "tagged-core" }

[dependencies]
tagged-core = { path = "tagged-core", version = "0.4.0", features = ["serde"] }
tagged-core = { path = "tagged-core", version = "0.5.0", features = ["serde"] }

[dev-dependencies]
serde = { version = "1.0.219", features = ["derive"] }
serde = { version = "1.0.210", features = ["derive", "rc"] }
serde_json = {version = "1.0.140"}


Expand Down
16 changes: 16 additions & 0 deletions examples/Into_iterators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
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
*/
12 changes: 1 addition & 11 deletions examples/Iter_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,10 @@ type EmployeeNames = Tagged<Vec<String>, Org>;

fn main() {
let names: EmployeeNames = Tagged::new(vec!["Alice".into(), "Bob".into()]);

for name in &names {
println!("Name: {name}");
}

// Consuming iterator
for name in names {
println!("Owned: {name}");
}
names.iter().for_each(|name| println!("Name: {}", name));
}

/*
Name: Alice
Name: Bob
Owned: Alice
Owned: Bob
*/
26 changes: 26 additions & 0 deletions examples/RC_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use rust_tagged::Tagged;
use std::rc::Rc;
use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct Org;

type OrgRef = Tagged<Rc<String>, Org>;

#[derive(Debug, Serialize, Deserialize)]
struct Project {
name: String,
org: OrgRef,
}

fn main() {
let shared = Rc::new("codefonsi.com".to_string());

let project = Project {
name: "Open Source".into(),
org: shared.clone().into(),
};

let json = serde_json::to_string(&project).unwrap();
println!("Serialized: {json}");
}
38 changes: 24 additions & 14 deletions examples/Serde_example.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
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() {
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
Expand Down
26 changes: 26 additions & 0 deletions examples/for_loop_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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()]);

for name in &names {
println!("Name: {name}");
}

// Consuming iterator
for name in names {
println!("Owned: {name}");
}
}

/*
Name: Alice
Name: Bob
Owned: Alice
Owned: Bob
*/
112 changes: 0 additions & 112 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,113 +1 @@
/// 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}");
/// }
/// ```
///
/// # 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);
/// }
/// ```
///
/// # 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));
/// }
/// ```
///
/// # Example - Iter
/// ```
/// 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()]);
///
/// for name in &names {
/// println!("Name: {name}");
/// }
///
/// // Consuming iterator
/// for name in names {
/// println!("Owned: {name}");
/// }
/// }
///
/// /*
/// Name: Alice
/// Name: Bob
/// Owned: Alice
/// Owned: Bob
/// */
/// ```
///
/// # Example - Mutation
/// ```
/// use tagged_core::Tagged;
///
/// #[derive(Debug)]
/// struct Org;
///
/// type OrgName = Tagged<String, Org>;
///
/// fn main() {
/// let mut name = OrgName::new("Codefonsi".into());
///
/// name.set("New Org Name".into());
///
/// println!("Updated Org Name: {}", name.value());
/// }
/// ```

pub use tagged_core::*;
5 changes: 3 additions & 2 deletions tagged-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tagged-core"
version = "0.4.0"
version = "0.5.0"
edition = "2024"
description = "A lightweight tagged type abstraction for type-safe IDs, etc."
license = "MPL-2.0"
Expand All @@ -14,9 +14,10 @@ readme = "../README.md"
include = ["src/**/*", "Cargo.toml", "../../README.md", "LICENSE"]

[dependencies]
serde = { version = "1.0.219", features = ["derive"], optional = true }
serde = { version = "1.0.210", features = ["derive", "rc"], optional = true }

[dev-dependencies]
serde_json = "1.0.140"
uuid = { version = "1.6" , features = ["v4"]}
chrono = "0.4.41"

Expand Down
Loading