1use serde::{Deserialize, Serialize};
2use ferrox_errors::AppError;
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7pub struct Pagination {
8 limit: u32,
9 offset: u32,
10}
11
12impl Pagination {
13 pub fn new(limit: u32, offset: u32) -> Result<Self, AppError> {
15 if limit == 0 {
16 return Err(AppError::ValidationError("Limit must be strictly greater than 0".into()));
17 }
18 if limit > 100 {
19 return Err(AppError::ValidationError("Limit cannot exceed 100".into()));
20 }
21
22 Ok(Self { limit, offset })
23 }
24
25 pub fn limit(&self) -> u32 {
26 self.limit
27 }
28
29 pub fn offset(&self) -> u32 {
30 self.offset
31 }
32}
33
34use validator::Validate;
35use ts_rs::TS;
36
37#[derive(Debug, Clone, Serialize, Deserialize, Validate, TS)]
40#[ts(export)]
41pub struct CreateUserDto {
42 #[validate(email)]
43 pub email: String,
44
45 #[validate(length(min = 8, message = "Password must be at least 8 characters"))]
46 pub password: String,
47
48 #[validate(range(min = 18, max = 130))]
49 pub age: u8,
50}
51
52pub fn setup() {
53 println!("ferrox-types initialized: Provides domain primitives and marker traits.");
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
62 fn test_pagination_validation_fails_on_zero_limit() {
63 let result = Pagination::new(0, 10);
64 assert!(result.is_err());
65 if let Err(AppError::ValidationError(msg)) = result {
66 assert_eq!(msg, "Limit must be strictly greater than 0");
67 } else {
68 panic!("Expected ValidationError");
69 }
70 }
71
72 #[test]
73 fn test_pagination_validation_fails_on_large_limit() {
74 let result = Pagination::new(101, 0);
75 assert!(result.is_err());
76 }
77
78 #[test]
79 fn test_pagination_creation_success() {
80 let pagination = Pagination::new(50, 20).unwrap();
81 assert_eq!(pagination.limit(), 50);
82 assert_eq!(pagination.offset(), 20);
83 }
84
85 #[test]
86 fn test_dto_validation() {
87 let bad_dto = CreateUserDto {
88 email: "invalid_email".into(),
89 password: "short".into(),
90 age: 15, };
92
93 let result = bad_dto.validate();
94 assert!(result.is_err());
95 let errs = result.unwrap_err();
96
97 let err_map = errs.field_errors();
99 assert!(err_map.contains_key("email"));
100 assert!(err_map.contains_key("password"));
101 assert!(err_map.contains_key("age"));
102 }
103}