1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/// Core trait for all value objects in arvo.
///
/// A value object is an immutable, validated wrapper around a raw value.
/// Construction via [`new`](ValueObject::new) is the **only** way to obtain
/// a valid instance — invalid states are unrepresentable at the type level.
///
/// # Type parameters
///
/// - `Input` — the type accepted by [`new`](ValueObject::new).
/// For simple types this is the raw primitive (e.g. `String`).
/// For composite types this is a dedicated input struct.
/// - `Error` — the error returned when validation fails.
///
/// Simple types (single-primitive wrappers) additionally implement
/// [`PrimitiveValue`], which exposes the inner value via [`value()`](PrimitiveValue::value).
/// Composite types expose their data through dedicated accessor methods instead.
///
/// # Example
///
/// ```rust,ignore
/// use arvo::traits::{ValueObject, PrimitiveValue};
/// use arvo::errors::ValidationError;
///
/// pub struct NonNegative(f64);
///
/// impl ValueObject for NonNegative {
/// type Input = f64;
/// type Error = ValidationError;
///
/// fn new(value: f64) -> Result<Self, ValidationError> {
/// if value < 0.0 {
/// return Err(ValidationError::invalid("NonNegative", &value.to_string()));
/// }
/// Ok(Self(value))
/// }
///
/// fn into_inner(self) -> f64 { self.0 }
/// }
///
/// impl PrimitiveValue for NonNegative {
/// type Primitive = f64;
/// fn value(&self) -> &f64 { &self.0 }
/// }
/// ```
/// Extension of [`ValueObject`] for simple single-primitive newtypes.
///
/// Implemented by every type whose validated representation is a single
/// primitive value (e.g. `EmailAddress` wraps `String`, `Latitude` wraps `f64`).
/// Composite types (e.g. `Money`, `PostalAddress`) do **not** implement this
/// trait — they expose their data through dedicated accessor methods.
///
/// # Example
///
/// ```rust,ignore
/// use arvo::contact::EmailAddress;
/// use arvo::traits::{ValueObject, PrimitiveValue};
///
/// let email = EmailAddress::new("user@example.com".into())?;
/// assert_eq!(email.value(), "user@example.com");
///
/// // Generic bound for code that only needs the inner primitive:
/// fn print_value<T: PrimitiveValue<Primitive = str>>(v: &T) {
/// println!("{}", v.value());
/// }
/// ```