Skip to content

Latest commit

 

History

History
356 lines (245 loc) · 7.85 KB

File metadata and controls

356 lines (245 loc) · 7.85 KB

primitives module

Feature flag: primitives

[dependencies]
arvo = { version = "1.0", features = ["primitives"] }

NonEmptyString

A non-empty, trimmed string.

Normalisation: surrounding whitespace trimmed.
Validation: must not be empty after trimming.

use arvo::primitives::NonEmptyString;
use arvo::traits::{PrimitiveValue, ValueObject};

let s = NonEmptyString::new("  hello  ".into())?;
assert_eq!(s.value(), "hello");

let s: NonEmptyString = "world".try_into()?;

Accessors

Method Returns Example
value() &String "hello"
into_inner() String "hello"

Errors

Input Error
"" ValidationError::Empty
" " ValidationError::Empty

BoundedString

A string whose length (in Unicode characters) is constrained at the type level.

Normalisation: surrounding whitespace trimmed.
Validation: character count (not byte count) must be >= MIN and <= MAX.

use arvo::primitives::BoundedString;
use arvo::traits::{PrimitiveValue, ValueObject};

type Username = BoundedString<3, 32>;

let name = Username::new("Alice".into())?;
assert_eq!(name.value(), "Alice");

assert!(Username::new("Al".into()).is_err()); // too short

Accessors

Method Returns Example
value() &String "Alice"
into_inner() String "Alice"

Errors

Input Error
value shorter than MIN ValidationError::OutOfRange
value longer than MAX ValidationError::OutOfRange

PositiveInt

A strictly positive integer (i64 > 0).

Normalisation: none.
Validation: value must be > 0. Zero and negative values are rejected.

use arvo::primitives::PositiveInt;
use arvo::traits::{PrimitiveValue, ValueObject};

let n = PositiveInt::new(42)?;
assert_eq!(*n.value(), 42);

assert!(PositiveInt::new(0).is_err());

Accessors

Method Returns Example
value() &i64 42
into_inner() i64 42

Errors

Input Error
0 ValidationError::OutOfRange
-1 ValidationError::OutOfRange

NonNegativeInt

A non-negative integer (i64 >= 0).

Normalisation: none.
Validation: value must be >= 0. Negative values are rejected.

use arvo::primitives::NonNegativeInt;
use arvo::traits::{PrimitiveValue, ValueObject};

let n = NonNegativeInt::new(0)?;
assert_eq!(*n.value(), 0);

assert!(NonNegativeInt::new(-1).is_err());

Accessors

Method Returns Example
value() &i64 0
into_inner() i64 0

Errors

Input Error
-1 ValidationError::OutOfRange

PositiveDecimal

A strictly positive decimal (rust_decimal::Decimal > 0).

Normalisation: none.
Validation: value must be > Decimal::ZERO.

use arvo::primitives::PositiveDecimal;
use arvo::traits::{PrimitiveValue, ValueObject};
use rust_decimal::Decimal;
use std::str::FromStr;

let price = PositiveDecimal::new(Decimal::from_str("9.99").unwrap())?;
assert_eq!(price.value(), &Decimal::from_str("9.99").unwrap());

Accessors

Method Returns Example
value() &Decimal 9.99
into_inner() Decimal 9.99

Errors

Input Error
Decimal::ZERO ValidationError::OutOfRange
negative value ValidationError::OutOfRange

NonNegativeDecimal

A non-negative decimal (rust_decimal::Decimal >= 0).

Normalisation: none.
Validation: value must be >= Decimal::ZERO.

use arvo::primitives::NonNegativeDecimal;
use arvo::traits::{PrimitiveValue, ValueObject};
use rust_decimal::Decimal;

let amount = NonNegativeDecimal::new(Decimal::ZERO)?;
assert_eq!(amount.value(), &Decimal::ZERO);

Accessors

Method Returns Example
value() &Decimal 0
into_inner() Decimal 0

Errors

Input Error
negative value ValidationError::OutOfRange

Probability

A probability value in the closed interval [0.0, 1.0].

Normalisation: none.
Validation: must be finite and in 0.0..=1.0. NaN and infinity are rejected.

use arvo::primitives::Probability;
use arvo::traits::{PrimitiveValue, ValueObject};

let p = Probability::new(0.75)?;
assert_eq!(*p.value(), 0.75);

assert!(Probability::new(1.5).is_err());
assert!(Probability::new(f64::NAN).is_err());

Accessors

Method Returns Example
value() &f64 0.75
into_inner() f64 0.75

Errors

Input Error
1.5 ValidationError::OutOfRange
-0.1 ValidationError::OutOfRange
NaN ValidationError::OutOfRange
ValidationError::OutOfRange

HexColor

A CSS hex color in canonical #RRGGBB form.

Normalisation: trimmed; uppercased; 3-digit shorthand expanded to 6-digit form (#F0A#FF00AA).
Validation: must start with #; remaining chars must be exactly 3 or 6 hexadecimal digits.

use arvo::primitives::HexColor;
use arvo::traits::{PrimitiveValue, ValueObject};

let red = HexColor::new("#f00".into())?;
assert_eq!(red.value(), "#FF0000");
assert_eq!(red.r(), 255);
assert_eq!(red.g(), 0);
assert_eq!(red.b(), 0);

let c: HexColor = "#1A2B3C".try_into()?;

Accessors

Method Returns Example
value() &String "#FF0000"
r() u8 255
g() u8 0
b() u8 0
to_rgb() (u8, u8, u8) (255, 0, 0)
into_inner() String "#FF0000"

Errors

Input Error
"" ValidationError::Empty
"FF0000" ValidationError::InvalidFormat (missing #)
"#GGGGGG" ValidationError::InvalidFormat
"#FFFF" ValidationError::InvalidFormat (wrong length)

Locale

A BCP 47 language tag (e.g. "en-US", "cs-CZ", "fr").

Normalisation: trimmed; _ separator normalised to -; language subtag lowercased; region subtag uppercased.
Validation (MVP): language subtag must be 2–3 ASCII letters; optional region subtag must be 2 ASCII letters or 3 digits.

use arvo::primitives::Locale;
use arvo::traits::{PrimitiveValue, ValueObject};

let locale = Locale::new("en_us".into())?;
assert_eq!(locale.value(), "en-US");

let fr: Locale = "fr".try_into()?;
assert_eq!(fr.value(), "fr");

Accessors

Method Returns Example
value() &String "en-US"
language() &str "en" (language subtag)
region() Option<&str> Some("US") / None for language-only tags
into_inner() String "en-US"

Errors

Input Error
"" ValidationError::Empty
"e" ValidationError::InvalidFormat (language too short)
"engl" ValidationError::InvalidFormat (language too long)
"en-X1" ValidationError::InvalidFormat (invalid region)

Base64String

A validated standard Base64-encoded string.

Normalisation: surrounding whitespace trimmed.
Validation: must decode successfully using the standard Base64 alphabet (A–Z, a–z, 0–9, +, /) with correct = padding.

use arvo::primitives::Base64String;
use arvo::traits::{PrimitiveValue, ValueObject};

let b = Base64String::new("aGVsbG8=".into())?;
assert_eq!(b.decode(), b"hello");

let b: Base64String = "aGVsbG8=".try_into()?;

Accessors

Method Returns Example
value() &String "aGVsbG8="
decode() Vec<u8> [104, 101, 108, 108, 111]
into_inner() String "aGVsbG8="

Errors

Input Error
"" ValidationError::Empty
"not!!valid" ValidationError::InvalidFormat
"aGVsbG8" ValidationError::InvalidFormat (invalid padding)