Skip to main content

reinhardt_db/orm/
fields.rs

1// Field definitions and deconstruction API
2// Corresponds to Django's field system
3
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7/// Field deconstruction result
8/// Returns (name, path, args, kwargs) similar to Django's deconstruct()
9#[derive(Debug, Clone, PartialEq)]
10pub struct FieldDeconstruction {
11	/// The name.
12	pub name: Option<String>,
13	/// The path.
14	pub path: String,
15	/// The args.
16	pub args: Vec<FieldArg>,
17	/// The kwargs.
18	pub kwargs: HashMap<String, FieldKwarg>,
19}
20
21/// Positional argument for field construction
22#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
23#[serde(untagged)]
24pub enum FieldArg {
25	/// String variant.
26	String(String),
27	/// Int variant.
28	Int(i64),
29	/// Bool variant.
30	Bool(bool),
31	/// Float variant.
32	Float(f64),
33}
34
35/// Keyword argument for field construction
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37#[serde(untagged)]
38pub enum FieldKwarg {
39	/// String variant.
40	String(String),
41	/// Int variant.
42	Int(i64),
43	/// Uint variant.
44	Uint(u64),
45	/// Bool variant.
46	Bool(bool),
47	/// Float variant.
48	Float(f64),
49	/// Choices variant.
50	Choices(Vec<(String, String)>),
51	/// Callable variant.
52	Callable(String), // Function name as string
53}
54
55/// Core Field trait - all field types implement this
56pub trait Field: Send + Sync {
57	/// Deconstruct the field into a serializable representation
58	/// Returns (name, path, args, kwargs)
59	fn deconstruct(&self) -> FieldDeconstruction;
60
61	/// Set field name and attributes from model introspection
62	fn set_attributes_from_name(&mut self, name: &str);
63
64	/// Get field name
65	fn name(&self) -> Option<&str>;
66
67	/// Check if field is a primary key
68	fn is_primary_key(&self) -> bool {
69		false
70	}
71
72	/// Check if field allows null
73	fn is_null(&self) -> bool {
74		false
75	}
76
77	/// Check if field allows blank
78	fn is_blank(&self) -> bool {
79		false
80	}
81}
82
83/// Base field attributes shared by all fields
84#[derive(Debug, Clone)]
85pub struct BaseField {
86	/// The name.
87	pub name: Option<String>,
88	/// The null.
89	pub null: bool,
90	/// The blank.
91	pub blank: bool,
92	/// The default.
93	pub default: Option<FieldKwarg>,
94	/// The db default.
95	pub db_default: Option<FieldKwarg>, // Database-level default value
96	/// The db column.
97	pub db_column: Option<String>,
98	/// The db tablespace.
99	pub db_tablespace: Option<String>,
100	/// The primary key.
101	pub primary_key: bool,
102	/// The unique.
103	pub unique: bool,
104	/// The editable.
105	pub editable: bool,
106	/// The choices.
107	pub choices: Option<Vec<(String, String)>>,
108}
109
110impl BaseField {
111	/// Creates a new BaseField with default values
112	///
113	/// # Examples
114	///
115	/// ```
116	/// use reinhardt_db::orm::fields::BaseField;
117	///
118	/// let field = BaseField::new();
119	/// assert!(!field.null);
120	/// assert!(!field.blank);
121	/// assert!(!field.primary_key);
122	/// assert!(!field.unique);
123	/// assert!(field.editable);
124	/// ```
125	pub fn new() -> Self {
126		Self {
127			name: None,
128			null: false,
129			blank: false,
130			default: None,
131			db_default: None,
132			db_column: None,
133			db_tablespace: None,
134			primary_key: false,
135			unique: false,
136			editable: true,
137			choices: None,
138		}
139	}
140	/// Extract non-default kwargs for deconstruction
141	///
142	/// # Examples
143	///
144	/// ```
145	/// use reinhardt_db::orm::fields::{BaseField, FieldKwarg};
146	/// use std::collections::HashMap;
147	///
148	/// let mut field = BaseField::new();
149	/// field.null = true;
150	/// field.blank = true;
151	/// field.primary_key = true;
152	///
153	/// let kwargs = field.get_kwargs();
154	/// assert_eq!(kwargs.get("null"), Some(&FieldKwarg::Bool(true)));
155	/// assert_eq!(kwargs.get("blank"), Some(&FieldKwarg::Bool(true)));
156	/// assert_eq!(kwargs.get("primary_key"), Some(&FieldKwarg::Bool(true)));
157	/// ```
158	pub fn get_kwargs(&self) -> HashMap<String, FieldKwarg> {
159		let mut kwargs = HashMap::new();
160
161		if self.null {
162			kwargs.insert("null".to_string(), FieldKwarg::Bool(true));
163		}
164		if self.blank {
165			kwargs.insert("blank".to_string(), FieldKwarg::Bool(true));
166		}
167		if let Some(ref default) = self.default {
168			kwargs.insert("default".to_string(), default.clone());
169		}
170		if let Some(ref db_default) = self.db_default {
171			kwargs.insert("db_default".to_string(), db_default.clone());
172		}
173		if let Some(ref db_column) = self.db_column {
174			kwargs.insert(
175				"db_column".to_string(),
176				FieldKwarg::String(db_column.clone()),
177			);
178		}
179		if let Some(ref db_tablespace) = self.db_tablespace {
180			kwargs.insert(
181				"db_tablespace".to_string(),
182				FieldKwarg::String(db_tablespace.clone()),
183			);
184		}
185		if self.primary_key {
186			kwargs.insert("primary_key".to_string(), FieldKwarg::Bool(true));
187		}
188		if self.unique {
189			kwargs.insert("unique".to_string(), FieldKwarg::Bool(true));
190		}
191		if !self.editable {
192			kwargs.insert("editable".to_string(), FieldKwarg::Bool(false));
193		}
194		if let Some(ref choices) = self.choices {
195			kwargs.insert("choices".to_string(), FieldKwarg::Choices(choices.clone()));
196		}
197
198		kwargs
199	}
200}
201
202impl Default for BaseField {
203	fn default() -> Self {
204		Self::new()
205	}
206}
207
208/// AutoField - auto-incrementing integer primary key
209#[derive(Debug, Clone)]
210pub struct AutoField {
211	/// The base.
212	pub base: BaseField,
213}
214
215impl Default for AutoField {
216	fn default() -> Self {
217		Self::new()
218	}
219}
220
221impl AutoField {
222	/// Create a new auto-incrementing primary key field
223	///
224	/// # Examples
225	///
226	/// ```
227	/// use reinhardt_db::orm::fields::{AutoField, Field};
228	///
229	/// let mut id_field = AutoField::new();
230	/// id_field.set_attributes_from_name("id");
231	/// assert!(id_field.is_primary_key());
232	/// assert_eq!(id_field.name(), Some("id"));
233	/// ```
234	pub fn new() -> Self {
235		let mut base = BaseField::new();
236		base.primary_key = true;
237		Self { base }
238	}
239}
240
241impl Field for AutoField {
242	fn deconstruct(&self) -> FieldDeconstruction {
243		let kwargs = self.base.get_kwargs();
244
245		FieldDeconstruction {
246			name: self.base.name.clone(),
247			path: "reinhardt.orm.models.AutoField".to_string(),
248			args: vec![],
249			kwargs,
250		}
251	}
252
253	fn set_attributes_from_name(&mut self, name: &str) {
254		self.base.name = Some(name.to_string());
255	}
256
257	fn name(&self) -> Option<&str> {
258		self.base.name.as_deref()
259	}
260
261	fn is_primary_key(&self) -> bool {
262		self.base.primary_key
263	}
264}
265
266/// BigIntegerField
267#[derive(Debug, Clone)]
268pub struct BigIntegerField {
269	/// The base.
270	pub base: BaseField,
271}
272
273impl Default for BigIntegerField {
274	fn default() -> Self {
275		Self::new()
276	}
277}
278
279impl BigIntegerField {
280	/// Create a new big integer field
281	///
282	/// # Examples
283	///
284	/// ```
285	/// use reinhardt_db::orm::fields::{BigIntegerField, Field};
286	///
287	/// let mut population_field = BigIntegerField::new();
288	/// population_field.set_attributes_from_name("population");
289	/// let deconstruction = population_field.deconstruct();
290	/// assert_eq!(deconstruction.path, "reinhardt.orm.models.BigIntegerField");
291	/// ```
292	pub fn new() -> Self {
293		Self {
294			base: BaseField::new(),
295		}
296	}
297}
298
299impl Field for BigIntegerField {
300	fn deconstruct(&self) -> FieldDeconstruction {
301		FieldDeconstruction {
302			name: self.base.name.clone(),
303			path: "reinhardt.orm.models.BigIntegerField".to_string(),
304			args: vec![],
305			kwargs: self.base.get_kwargs(),
306		}
307	}
308
309	fn set_attributes_from_name(&mut self, name: &str) {
310		self.base.name = Some(name.to_string());
311	}
312
313	fn name(&self) -> Option<&str> {
314		self.base.name.as_deref()
315	}
316}
317
318/// BooleanField
319#[derive(Debug, Clone)]
320pub struct BooleanField {
321	/// The base.
322	pub base: BaseField,
323}
324
325impl Default for BooleanField {
326	fn default() -> Self {
327		Self::new()
328	}
329}
330
331impl BooleanField {
332	/// Create a new boolean field
333	///
334	/// # Examples
335	///
336	/// ```
337	/// use reinhardt_db::orm::fields::BooleanField;
338	///
339	/// let is_active = BooleanField::new();
340	/// ```
341	pub fn new() -> Self {
342		Self {
343			base: BaseField::new(),
344		}
345	}
346	/// Create a boolean field with a default value
347	///
348	/// # Examples
349	///
350	/// ```
351	/// use reinhardt_db::orm::fields::{BooleanField, Field, FieldKwarg};
352	///
353	/// let is_active = BooleanField::with_default(true);
354	/// let dec = is_active.deconstruct();
355	/// assert_eq!(dec.kwargs.get("default"), Some(&FieldKwarg::Bool(true)));
356	/// ```
357	pub fn with_default(default: bool) -> Self {
358		let mut field = Self::new();
359		field.base.default = Some(FieldKwarg::Bool(default));
360		field
361	}
362}
363
364impl Field for BooleanField {
365	fn deconstruct(&self) -> FieldDeconstruction {
366		FieldDeconstruction {
367			name: self.base.name.clone(),
368			path: "reinhardt.orm.models.BooleanField".to_string(),
369			args: vec![],
370			kwargs: self.base.get_kwargs(),
371		}
372	}
373
374	fn set_attributes_from_name(&mut self, name: &str) {
375		self.base.name = Some(name.to_string());
376	}
377
378	fn name(&self) -> Option<&str> {
379		self.base.name.as_deref()
380	}
381}
382
383/// CharField - text field with max_length
384#[derive(Debug, Clone)]
385pub struct CharField {
386	/// The base.
387	pub base: BaseField,
388	/// The max length.
389	pub max_length: u64,
390}
391
392impl CharField {
393	/// Create a new character field with maximum length
394	///
395	/// # Examples
396	///
397	/// ```
398	/// use reinhardt_db::orm::fields::{CharField, Field, FieldKwarg};
399	///
400	/// let username_field = CharField::new(150);
401	/// let dec = username_field.deconstruct();
402	/// assert_eq!(dec.kwargs.get("max_length"), Some(&FieldKwarg::Uint(150)));
403	/// ```
404	pub fn new(max_length: u64) -> Self {
405		Self {
406			base: BaseField::new(),
407			max_length,
408		}
409	}
410	/// Create a character field that allows NULL and blank values
411	///
412	/// # Examples
413	///
414	/// ```
415	/// use reinhardt_db::orm::fields::{CharField, Field, FieldKwarg};
416	///
417	/// let middle_name = CharField::with_null_blank(100);
418	/// let dec = middle_name.deconstruct();
419	/// assert_eq!(dec.kwargs.get("null"), Some(&FieldKwarg::Bool(true)));
420	/// assert_eq!(dec.kwargs.get("blank"), Some(&FieldKwarg::Bool(true)));
421	/// ```
422	pub fn with_null_blank(max_length: u64) -> Self {
423		let mut base = BaseField::new();
424		base.null = true;
425		base.blank = true;
426		Self { base, max_length }
427	}
428	/// Create a character field with predefined choices
429	///
430	/// # Examples
431	///
432	/// ```
433	/// use reinhardt_db::orm::fields::CharField;
434	///
435	/// let status = CharField::with_choices(
436	///     10,
437	///     vec![
438	///         ("draft".to_string(), "Draft".to_string()),
439	///         ("published".to_string(), "Published".to_string()),
440	///     ],
441	/// );
442	/// ```
443	pub fn with_choices(max_length: u64, choices: Vec<(String, String)>) -> Self {
444		let mut base = BaseField::new();
445		base.choices = Some(choices);
446		Self { base, max_length }
447	}
448}
449
450impl Field for CharField {
451	fn deconstruct(&self) -> FieldDeconstruction {
452		let mut kwargs = self.base.get_kwargs();
453		kwargs.insert("max_length".to_string(), FieldKwarg::Uint(self.max_length));
454
455		FieldDeconstruction {
456			name: self.base.name.clone(),
457			path: "reinhardt.orm.models.CharField".to_string(),
458			args: vec![],
459			kwargs,
460		}
461	}
462
463	fn set_attributes_from_name(&mut self, name: &str) {
464		self.base.name = Some(name.to_string());
465	}
466
467	fn name(&self) -> Option<&str> {
468		self.base.name.as_deref()
469	}
470}
471
472/// IntegerField
473#[derive(Debug, Clone)]
474pub struct IntegerField {
475	/// The base.
476	pub base: BaseField,
477}
478
479impl Default for IntegerField {
480	fn default() -> Self {
481		Self::new()
482	}
483}
484
485impl IntegerField {
486	/// Create a new IntegerField
487	///
488	/// # Examples
489	///
490	/// ```
491	/// use reinhardt_db::orm::fields::IntegerField;
492	///
493	/// let field = IntegerField::new();
494	/// assert!(field.base.choices.is_none());
495	/// ```
496	pub fn new() -> Self {
497		Self {
498			base: BaseField::new(),
499		}
500	}
501	///
502	/// # Examples
503	///
504	/// ```
505	/// use reinhardt_db::orm::fields::IntegerField;
506	///
507	/// let choices = vec![
508	///     ("1".to_string(), "Option 1".to_string()),
509	///     ("2".to_string(), "Option 2".to_string()),
510	/// ];
511	/// let field = IntegerField::with_choices(choices.clone());
512	/// assert_eq!(field.base.choices.unwrap().len(), 2);
513	/// ```
514	pub fn with_choices(choices: Vec<(String, String)>) -> Self {
515		let mut base = BaseField::new();
516		base.choices = Some(choices);
517		Self { base }
518	}
519	///
520	/// # Examples
521	///
522	/// ```
523	/// use reinhardt_db::orm::fields::IntegerField;
524	///
525	/// let field = IntegerField::with_callable_choices("get_status_choices");
526	/// // The callable name would be used to dynamically generate choices at runtime
527	/// assert!(field.base.choices.is_none()); // Callable choices are handled separately
528	/// ```
529	pub fn with_callable_choices(_callable_name: &str) -> Self {
530		// Store callable as a special marker in base
531
532		// We'll handle callable differently in deconstruct
533		Self::new()
534	}
535}
536
537impl Field for IntegerField {
538	fn deconstruct(&self) -> FieldDeconstruction {
539		FieldDeconstruction {
540			name: self.base.name.clone(),
541			path: "reinhardt.orm.models.IntegerField".to_string(),
542			args: vec![],
543			kwargs: self.base.get_kwargs(),
544		}
545	}
546
547	fn set_attributes_from_name(&mut self, name: &str) {
548		self.base.name = Some(name.to_string());
549	}
550
551	fn name(&self) -> Option<&str> {
552		self.base.name.as_deref()
553	}
554}
555
556/// DateField
557#[derive(Debug, Clone)]
558pub struct DateField {
559	/// The base.
560	pub base: BaseField,
561	/// The auto now.
562	pub auto_now: bool,
563	/// The auto now add.
564	pub auto_now_add: bool,
565}
566
567impl Default for DateField {
568	fn default() -> Self {
569		Self::new()
570	}
571}
572
573impl DateField {
574	/// Create a new DateField without auto timestamps
575	///
576	/// # Examples
577	///
578	/// ```
579	/// use reinhardt_db::orm::fields::DateField;
580	///
581	/// let field = DateField::new();
582	/// assert!(!field.auto_now);
583	/// assert!(!field.auto_now_add);
584	/// ```
585	pub fn new() -> Self {
586		Self {
587			base: BaseField::new(),
588			auto_now: false,
589			auto_now_add: false,
590		}
591	}
592	/// Create DateField that auto-updates on every save (like Django's auto_now)
593	///
594	/// # Examples
595	///
596	/// ```
597	/// use reinhardt_db::orm::fields::DateField;
598	///
599	/// let field = DateField::with_auto_now();
600	/// assert!(field.auto_now);
601	/// assert!(!field.auto_now_add);
602	/// ```
603	pub fn with_auto_now() -> Self {
604		Self {
605			base: BaseField::new(),
606			auto_now: true,
607			auto_now_add: false,
608		}
609	}
610}
611
612impl Field for DateField {
613	fn deconstruct(&self) -> FieldDeconstruction {
614		let mut kwargs = self.base.get_kwargs();
615		if self.auto_now {
616			kwargs.insert("auto_now".to_string(), FieldKwarg::Bool(true));
617		}
618		if self.auto_now_add {
619			kwargs.insert("auto_now_add".to_string(), FieldKwarg::Bool(true));
620		}
621
622		FieldDeconstruction {
623			name: self.base.name.clone(),
624			path: "reinhardt.orm.models.DateField".to_string(),
625			args: vec![],
626			kwargs,
627		}
628	}
629
630	fn set_attributes_from_name(&mut self, name: &str) {
631		self.base.name = Some(name.to_string());
632	}
633
634	fn name(&self) -> Option<&str> {
635		self.base.name.as_deref()
636	}
637}
638
639/// DateTimeField
640#[derive(Debug, Clone)]
641pub struct DateTimeField {
642	/// The base.
643	pub base: BaseField,
644	/// The auto now.
645	pub auto_now: bool,
646	/// The auto now add.
647	pub auto_now_add: bool,
648}
649
650impl Default for DateTimeField {
651	fn default() -> Self {
652		Self::new()
653	}
654}
655
656impl DateTimeField {
657	/// Create a new DateTimeField without auto timestamps
658	///
659	/// # Examples
660	///
661	/// ```
662	/// use reinhardt_db::orm::fields::DateTimeField;
663	///
664	/// let field = DateTimeField::new();
665	/// assert!(!field.auto_now);
666	/// assert!(!field.auto_now_add);
667	/// ```
668	pub fn new() -> Self {
669		Self {
670			base: BaseField::new(),
671			auto_now: false,
672			auto_now_add: false,
673		}
674	}
675	/// Create DateTimeField that auto-sets on creation (like Django's auto_now_add)
676	///
677	/// # Examples
678	///
679	/// ```
680	/// use reinhardt_db::orm::fields::DateTimeField;
681	///
682	/// let field = DateTimeField::with_auto_now_add();
683	/// assert!(!field.auto_now);
684	/// assert!(field.auto_now_add);
685	/// ```
686	pub fn with_auto_now_add() -> Self {
687		Self {
688			base: BaseField::new(),
689			auto_now: false,
690			auto_now_add: true,
691		}
692	}
693	/// Create DateTimeField with both auto_now and auto_now_add enabled
694	///
695	/// # Examples
696	///
697	/// ```
698	/// use reinhardt_db::orm::fields::DateTimeField;
699	///
700	/// let field = DateTimeField::with_both();
701	/// assert!(field.auto_now);
702	/// assert!(field.auto_now_add);
703	/// ```
704	pub fn with_both() -> Self {
705		Self {
706			base: BaseField::new(),
707			auto_now: true,
708			auto_now_add: true,
709		}
710	}
711}
712
713impl Field for DateTimeField {
714	fn deconstruct(&self) -> FieldDeconstruction {
715		let mut kwargs = self.base.get_kwargs();
716		if self.auto_now {
717			kwargs.insert("auto_now".to_string(), FieldKwarg::Bool(true));
718		}
719		if self.auto_now_add {
720			kwargs.insert("auto_now_add".to_string(), FieldKwarg::Bool(true));
721		}
722
723		FieldDeconstruction {
724			name: self.base.name.clone(),
725			path: "reinhardt.orm.models.DateTimeField".to_string(),
726			args: vec![],
727			kwargs,
728		}
729	}
730
731	fn set_attributes_from_name(&mut self, name: &str) {
732		self.base.name = Some(name.to_string());
733	}
734
735	fn name(&self) -> Option<&str> {
736		self.base.name.as_deref()
737	}
738}
739
740/// DecimalField
741#[derive(Debug, Clone)]
742pub struct DecimalField {
743	/// The base.
744	pub base: BaseField,
745	/// The max digits.
746	pub max_digits: u32,
747	/// The decimal places.
748	pub decimal_places: u32,
749}
750
751impl DecimalField {
752	/// Create a new DecimalField with precision settings
753	///
754	/// # Examples
755	///
756	/// ```
757	/// use reinhardt_db::orm::fields::DecimalField;
758	///
759	/// // For monetary values: max 10 digits, 2 decimal places
760	/// let price_field = DecimalField::new(10, 2);
761	/// assert_eq!(price_field.max_digits, 10);
762	/// assert_eq!(price_field.decimal_places, 2);
763	/// ```
764	pub fn new(max_digits: u32, decimal_places: u32) -> Self {
765		Self {
766			base: BaseField::new(),
767			max_digits,
768			decimal_places,
769		}
770	}
771}
772
773impl Field for DecimalField {
774	fn deconstruct(&self) -> FieldDeconstruction {
775		let mut kwargs = self.base.get_kwargs();
776		kwargs.insert(
777			"max_digits".to_string(),
778			FieldKwarg::Uint(self.max_digits as u64),
779		);
780		kwargs.insert(
781			"decimal_places".to_string(),
782			FieldKwarg::Uint(self.decimal_places as u64),
783		);
784
785		FieldDeconstruction {
786			name: self.base.name.clone(),
787			path: "reinhardt.orm.models.DecimalField".to_string(),
788			args: vec![],
789			kwargs,
790		}
791	}
792
793	fn set_attributes_from_name(&mut self, name: &str) {
794		self.base.name = Some(name.to_string());
795	}
796
797	fn name(&self) -> Option<&str> {
798		self.base.name.as_deref()
799	}
800}
801
802/// EmailField
803#[derive(Debug, Clone)]
804pub struct EmailField {
805	/// The base.
806	pub base: BaseField,
807	/// The max length.
808	pub max_length: u64,
809}
810
811impl Default for EmailField {
812	fn default() -> Self {
813		Self::new()
814	}
815}
816
817impl EmailField {
818	/// Create a new EmailField with Django's default max_length (254)
819	///
820	/// # Examples
821	///
822	/// ```
823	/// use reinhardt_db::orm::fields::EmailField;
824	///
825	/// let field = EmailField::new();
826	/// assert_eq!(field.max_length, 254);
827	/// ```
828	pub fn new() -> Self {
829		Self {
830			base: BaseField::new(),
831			max_length: 254, // Django default
832		}
833	}
834	/// Create EmailField with custom max_length
835	///
836	/// # Examples
837	///
838	/// ```
839	/// use reinhardt_db::orm::fields::EmailField;
840	///
841	/// let field = EmailField::with_max_length(100);
842	/// assert_eq!(field.max_length, 100);
843	/// ```
844	pub fn with_max_length(max_length: u64) -> Self {
845		Self {
846			base: BaseField::new(),
847			max_length,
848		}
849	}
850}
851
852impl Field for EmailField {
853	fn deconstruct(&self) -> FieldDeconstruction {
854		let mut kwargs = self.base.get_kwargs();
855		kwargs.insert("max_length".to_string(), FieldKwarg::Uint(self.max_length));
856
857		FieldDeconstruction {
858			name: self.base.name.clone(),
859			path: "reinhardt.orm.models.EmailField".to_string(),
860			args: vec![],
861			kwargs,
862		}
863	}
864
865	fn set_attributes_from_name(&mut self, name: &str) {
866		self.base.name = Some(name.to_string());
867	}
868
869	fn name(&self) -> Option<&str> {
870		self.base.name.as_deref()
871	}
872}
873
874/// FloatField
875#[derive(Debug, Clone)]
876pub struct FloatField {
877	/// The base.
878	pub base: BaseField,
879}
880
881impl Default for FloatField {
882	fn default() -> Self {
883		Self::new()
884	}
885}
886
887impl FloatField {
888	/// Create a new FloatField for storing floating-point numbers
889	///
890	/// # Examples
891	///
892	/// ```
893	/// use reinhardt_db::orm::fields::FloatField;
894	///
895	/// let field = FloatField::new();
896	/// assert!(field.base.choices.is_none());
897	/// ```
898	pub fn new() -> Self {
899		Self {
900			base: BaseField::new(),
901		}
902	}
903}
904
905impl Field for FloatField {
906	fn deconstruct(&self) -> FieldDeconstruction {
907		FieldDeconstruction {
908			name: self.base.name.clone(),
909			path: "reinhardt.orm.models.FloatField".to_string(),
910			args: vec![],
911			kwargs: self.base.get_kwargs(),
912		}
913	}
914
915	fn set_attributes_from_name(&mut self, name: &str) {
916		self.base.name = Some(name.to_string());
917	}
918
919	fn name(&self) -> Option<&str> {
920		self.base.name.as_deref()
921	}
922}
923
924/// TextField
925#[derive(Debug, Clone)]
926pub struct TextField {
927	/// The base.
928	pub base: BaseField,
929}
930
931impl Default for TextField {
932	fn default() -> Self {
933		Self::new()
934	}
935}
936
937impl TextField {
938	/// Create a new TextField for storing large text
939	///
940	/// # Examples
941	///
942	/// ```
943	/// use reinhardt_db::orm::fields::TextField;
944	///
945	/// let field = TextField::new();
946	/// assert!(field.base.name.is_none());
947	/// assert!(!field.base.null);
948	/// ```
949	pub fn new() -> Self {
950		Self {
951			base: BaseField::new(),
952		}
953	}
954}
955
956impl Field for TextField {
957	fn deconstruct(&self) -> FieldDeconstruction {
958		FieldDeconstruction {
959			name: self.base.name.clone(),
960			path: "reinhardt.orm.models.TextField".to_string(),
961			args: vec![],
962			kwargs: self.base.get_kwargs(),
963		}
964	}
965
966	fn set_attributes_from_name(&mut self, name: &str) {
967		self.base.name = Some(name.to_string());
968	}
969
970	fn name(&self) -> Option<&str> {
971		self.base.name.as_deref()
972	}
973}
974
975/// TimeField
976#[derive(Debug, Clone)]
977pub struct TimeField {
978	/// The base.
979	pub base: BaseField,
980	/// The auto now.
981	pub auto_now: bool,
982	/// The auto now add.
983	pub auto_now_add: bool,
984}
985
986impl Default for TimeField {
987	fn default() -> Self {
988		Self::new()
989	}
990}
991
992impl TimeField {
993	/// Create a new TimeField for storing time values
994	///
995	/// # Examples
996	///
997	/// ```
998	/// use reinhardt_db::orm::fields::TimeField;
999	///
1000	/// let field = TimeField::new();
1001	/// assert!(!field.auto_now);
1002	/// assert!(!field.auto_now_add);
1003	/// ```
1004	pub fn new() -> Self {
1005		Self {
1006			base: BaseField::new(),
1007			auto_now: false,
1008			auto_now_add: false,
1009		}
1010	}
1011	/// Documentation for `with_auto_now`
1012	pub fn with_auto_now() -> Self {
1013		Self {
1014			base: BaseField::new(),
1015			auto_now: true,
1016			auto_now_add: false,
1017		}
1018	}
1019	/// Documentation for `with_auto_now_add`
1020	pub fn with_auto_now_add() -> Self {
1021		Self {
1022			base: BaseField::new(),
1023			auto_now: false,
1024			auto_now_add: true,
1025		}
1026	}
1027}
1028
1029impl Field for TimeField {
1030	fn deconstruct(&self) -> FieldDeconstruction {
1031		let mut kwargs = self.base.get_kwargs();
1032		if self.auto_now {
1033			kwargs.insert("auto_now".to_string(), FieldKwarg::Bool(true));
1034		}
1035		if self.auto_now_add {
1036			kwargs.insert("auto_now_add".to_string(), FieldKwarg::Bool(true));
1037		}
1038
1039		FieldDeconstruction {
1040			name: self.base.name.clone(),
1041			path: "reinhardt.orm.models.TimeField".to_string(),
1042			args: vec![],
1043			kwargs,
1044		}
1045	}
1046
1047	fn set_attributes_from_name(&mut self, name: &str) {
1048		self.base.name = Some(name.to_string());
1049	}
1050
1051	fn name(&self) -> Option<&str> {
1052		self.base.name.as_deref()
1053	}
1054}
1055
1056/// URLField
1057#[derive(Debug, Clone)]
1058pub struct URLField {
1059	/// The base.
1060	pub base: BaseField,
1061	/// The max length.
1062	pub max_length: u64,
1063}
1064
1065impl Default for URLField {
1066	fn default() -> Self {
1067		Self::new()
1068	}
1069}
1070
1071impl URLField {
1072	/// Create a new URLField for storing and validating URLs
1073	///
1074	/// # Examples
1075	///
1076	/// ```
1077	/// use reinhardt_db::orm::fields::URLField;
1078	///
1079	/// let field = URLField::new();
1080	/// assert_eq!(field.max_length, 200); // Django's default
1081	/// ```
1082	pub fn new() -> Self {
1083		Self {
1084			base: BaseField::new(),
1085			max_length: 200, // Django default
1086		}
1087	}
1088	/// Documentation for `with_max_length`
1089	pub fn with_max_length(max_length: u64) -> Self {
1090		Self {
1091			base: BaseField::new(),
1092			max_length,
1093		}
1094	}
1095}
1096
1097impl Field for URLField {
1098	fn deconstruct(&self) -> FieldDeconstruction {
1099		let mut kwargs = self.base.get_kwargs();
1100		// Only include max_length if it's not the default
1101		if self.max_length != 200 {
1102			kwargs.insert("max_length".to_string(), FieldKwarg::Uint(self.max_length));
1103		}
1104
1105		FieldDeconstruction {
1106			name: self.base.name.clone(),
1107			path: "reinhardt.orm.models.URLField".to_string(),
1108			args: vec![],
1109			kwargs,
1110		}
1111	}
1112
1113	fn set_attributes_from_name(&mut self, name: &str) {
1114		self.base.name = Some(name.to_string());
1115	}
1116
1117	fn name(&self) -> Option<&str> {
1118		self.base.name.as_deref()
1119	}
1120}
1121
1122/// BinaryField
1123#[derive(Debug, Clone)]
1124pub struct BinaryField {
1125	/// The base.
1126	pub base: BaseField,
1127}
1128
1129impl Default for BinaryField {
1130	fn default() -> Self {
1131		Self::new()
1132	}
1133}
1134
1135impl BinaryField {
1136	/// Create a new BinaryField for storing raw binary data (not editable by default)
1137	///
1138	/// # Examples
1139	///
1140	/// ```
1141	/// use reinhardt_db::orm::fields::BinaryField;
1142	///
1143	/// let field = BinaryField::new();
1144	/// assert!(!field.base.editable); // Binary fields are not editable by default
1145	/// ```
1146	pub fn new() -> Self {
1147		let mut base = BaseField::new();
1148		base.editable = false; // Django default
1149		Self { base }
1150	}
1151	/// Create BinaryField that is editable in forms
1152	///
1153	/// # Examples
1154	///
1155	/// ```
1156	/// use reinhardt_db::orm::fields::BinaryField;
1157	///
1158	/// let field = BinaryField::with_editable();
1159	/// assert!(field.base.editable);
1160	/// ```
1161	pub fn with_editable() -> Self {
1162		let mut base = BaseField::new();
1163		base.editable = true;
1164		Self { base }
1165	}
1166}
1167
1168impl Field for BinaryField {
1169	fn deconstruct(&self) -> FieldDeconstruction {
1170		let mut kwargs = self.base.get_kwargs();
1171		// BinaryField default is editable=false, so remove it from kwargs if false
1172		// but add it if true (non-default)
1173		kwargs.remove("editable");
1174		if self.base.editable {
1175			kwargs.insert("editable".to_string(), FieldKwarg::Bool(true));
1176		}
1177
1178		FieldDeconstruction {
1179			name: self.base.name.clone(),
1180			path: "reinhardt.orm.models.BinaryField".to_string(),
1181			args: vec![],
1182			kwargs,
1183		}
1184	}
1185
1186	fn set_attributes_from_name(&mut self, name: &str) {
1187		self.base.name = Some(name.to_string());
1188	}
1189
1190	fn name(&self) -> Option<&str> {
1191		self.base.name.as_deref()
1192	}
1193}
1194
1195/// SlugField
1196#[derive(Debug, Clone)]
1197pub struct SlugField {
1198	/// The base.
1199	pub base: BaseField,
1200	/// The max length.
1201	pub max_length: u64,
1202	/// The db index.
1203	pub db_index: bool,
1204}
1205
1206impl Default for SlugField {
1207	fn default() -> Self {
1208		Self::new()
1209	}
1210}
1211
1212impl SlugField {
1213	/// Create a new SlugField for URL-friendly strings
1214	///
1215	/// # Examples
1216	///
1217	/// ```
1218	/// use reinhardt_db::orm::fields::SlugField;
1219	///
1220	/// let field = SlugField::new();
1221	/// assert_eq!(field.max_length, 50); // Django's default
1222	/// assert!(field.db_index); // Automatically indexed
1223	/// ```
1224	pub fn new() -> Self {
1225		Self {
1226			base: BaseField::new(),
1227			max_length: 50, // Django default
1228			db_index: true, // Django default
1229		}
1230	}
1231	/// Documentation for `with_options`
1232	pub fn with_options(max_length: u64, db_index: bool) -> Self {
1233		Self {
1234			base: BaseField::new(),
1235			max_length,
1236			db_index,
1237		}
1238	}
1239}
1240
1241impl Field for SlugField {
1242	fn deconstruct(&self) -> FieldDeconstruction {
1243		let mut kwargs = self.base.get_kwargs();
1244		// Only include non-default values
1245		if self.max_length != 50 {
1246			kwargs.insert("max_length".to_string(), FieldKwarg::Uint(self.max_length));
1247		}
1248		if !self.db_index {
1249			kwargs.insert("db_index".to_string(), FieldKwarg::Bool(false));
1250		}
1251
1252		FieldDeconstruction {
1253			name: self.base.name.clone(),
1254			path: "reinhardt.orm.models.SlugField".to_string(),
1255			args: vec![],
1256			kwargs,
1257		}
1258	}
1259
1260	fn set_attributes_from_name(&mut self, name: &str) {
1261		self.base.name = Some(name.to_string());
1262	}
1263
1264	fn name(&self) -> Option<&str> {
1265		self.base.name.as_deref()
1266	}
1267}
1268
1269/// SmallIntegerField
1270#[derive(Debug, Clone)]
1271pub struct SmallIntegerField {
1272	/// The base.
1273	pub base: BaseField,
1274}
1275
1276impl Default for SmallIntegerField {
1277	fn default() -> Self {
1278		Self::new()
1279	}
1280}
1281
1282impl SmallIntegerField {
1283	/// Create a new SmallIntegerField for small integers (-32768 to 32767)
1284	///
1285	/// # Examples
1286	///
1287	/// ```
1288	/// use reinhardt_db::orm::fields::SmallIntegerField;
1289	///
1290	/// let field = SmallIntegerField::new();
1291	/// assert!(field.base.name.is_none());
1292	/// ```
1293	pub fn new() -> Self {
1294		Self {
1295			base: BaseField::new(),
1296		}
1297	}
1298}
1299
1300impl Field for SmallIntegerField {
1301	fn deconstruct(&self) -> FieldDeconstruction {
1302		FieldDeconstruction {
1303			name: self.base.name.clone(),
1304			path: "reinhardt.orm.models.SmallIntegerField".to_string(),
1305			args: vec![],
1306			kwargs: self.base.get_kwargs(),
1307		}
1308	}
1309
1310	fn set_attributes_from_name(&mut self, name: &str) {
1311		self.base.name = Some(name.to_string());
1312	}
1313
1314	fn name(&self) -> Option<&str> {
1315		self.base.name.as_deref()
1316	}
1317}
1318
1319/// PositiveIntegerField
1320#[derive(Debug, Clone)]
1321pub struct PositiveIntegerField {
1322	/// The base.
1323	pub base: BaseField,
1324}
1325
1326impl Default for PositiveIntegerField {
1327	fn default() -> Self {
1328		Self::new()
1329	}
1330}
1331
1332impl PositiveIntegerField {
1333	/// Create a new PositiveIntegerField for positive integers (0 to 2147483647)
1334	///
1335	/// # Examples
1336	///
1337	/// ```
1338	/// use reinhardt_db::orm::fields::PositiveIntegerField;
1339	///
1340	/// let field = PositiveIntegerField::new();
1341	/// assert!(field.base.name.is_none());
1342	/// ```
1343	pub fn new() -> Self {
1344		Self {
1345			base: BaseField::new(),
1346		}
1347	}
1348}
1349
1350impl Field for PositiveIntegerField {
1351	fn deconstruct(&self) -> FieldDeconstruction {
1352		FieldDeconstruction {
1353			name: self.base.name.clone(),
1354			path: "reinhardt.orm.models.PositiveIntegerField".to_string(),
1355			args: vec![],
1356			kwargs: self.base.get_kwargs(),
1357		}
1358	}
1359
1360	fn set_attributes_from_name(&mut self, name: &str) {
1361		self.base.name = Some(name.to_string());
1362	}
1363
1364	fn name(&self) -> Option<&str> {
1365		self.base.name.as_deref()
1366	}
1367}
1368
1369/// PositiveSmallIntegerField
1370#[derive(Debug, Clone)]
1371pub struct PositiveSmallIntegerField {
1372	/// The base.
1373	pub base: BaseField,
1374}
1375
1376impl Default for PositiveSmallIntegerField {
1377	fn default() -> Self {
1378		Self::new()
1379	}
1380}
1381
1382impl PositiveSmallIntegerField {
1383	/// Create a new PositiveSmallIntegerField for small positive integers (0 to 32767)
1384	///
1385	/// # Examples
1386	///
1387	/// ```
1388	/// use reinhardt_db::orm::fields::PositiveSmallIntegerField;
1389	///
1390	/// let field = PositiveSmallIntegerField::new();
1391	/// assert!(field.base.name.is_none());
1392	/// ```
1393	pub fn new() -> Self {
1394		Self {
1395			base: BaseField::new(),
1396		}
1397	}
1398}
1399
1400impl Field for PositiveSmallIntegerField {
1401	fn deconstruct(&self) -> FieldDeconstruction {
1402		FieldDeconstruction {
1403			name: self.base.name.clone(),
1404			path: "reinhardt.orm.models.PositiveSmallIntegerField".to_string(),
1405			args: vec![],
1406			kwargs: self.base.get_kwargs(),
1407		}
1408	}
1409
1410	fn set_attributes_from_name(&mut self, name: &str) {
1411		self.base.name = Some(name.to_string());
1412	}
1413
1414	fn name(&self) -> Option<&str> {
1415		self.base.name.as_deref()
1416	}
1417}
1418
1419/// PositiveBigIntegerField
1420#[derive(Debug, Clone)]
1421pub struct PositiveBigIntegerField {
1422	/// The base.
1423	pub base: BaseField,
1424}
1425
1426impl Default for PositiveBigIntegerField {
1427	fn default() -> Self {
1428		Self::new()
1429	}
1430}
1431
1432impl PositiveBigIntegerField {
1433	/// Create a new PositiveBigIntegerField for large positive integers (0 to 9223372036854775807)
1434	///
1435	/// # Examples
1436	///
1437	/// ```
1438	/// use reinhardt_db::orm::fields::PositiveBigIntegerField;
1439	///
1440	/// let field = PositiveBigIntegerField::new();
1441	/// assert!(field.base.name.is_none());
1442	/// ```
1443	pub fn new() -> Self {
1444		Self {
1445			base: BaseField::new(),
1446		}
1447	}
1448}
1449
1450impl Field for PositiveBigIntegerField {
1451	fn deconstruct(&self) -> FieldDeconstruction {
1452		FieldDeconstruction {
1453			name: self.base.name.clone(),
1454			path: "reinhardt.orm.models.PositiveBigIntegerField".to_string(),
1455			args: vec![],
1456			kwargs: self.base.get_kwargs(),
1457		}
1458	}
1459
1460	fn set_attributes_from_name(&mut self, name: &str) {
1461		self.base.name = Some(name.to_string());
1462	}
1463
1464	fn name(&self) -> Option<&str> {
1465		self.base.name.as_deref()
1466	}
1467}
1468
1469/// GenericIPAddressField - IPv4 or IPv6 address field
1470#[derive(Debug, Clone)]
1471pub struct GenericIPAddressField {
1472	/// The base.
1473	pub base: BaseField,
1474	/// The protocol.
1475	pub protocol: String, // "both", "IPv4", "IPv6"
1476	/// The unpack ipv4.
1477	pub unpack_ipv4: bool,
1478}
1479
1480impl Default for GenericIPAddressField {
1481	fn default() -> Self {
1482		Self::new()
1483	}
1484}
1485
1486impl GenericIPAddressField {
1487	/// Create a new GenericIPAddressField for storing IP addresses (IPv4 and/or IPv6)
1488	///
1489	/// # Examples
1490	///
1491	/// ```
1492	/// use reinhardt_db::orm::fields::GenericIPAddressField;
1493	///
1494	/// let field = GenericIPAddressField::new();
1495	/// assert_eq!(field.protocol, "both"); // Accepts both IPv4 and IPv6
1496	/// assert!(!field.unpack_ipv4); // Don't unpack IPv4-mapped IPv6 addresses
1497	/// ```
1498	pub fn new() -> Self {
1499		Self {
1500			base: BaseField::new(),
1501			protocol: "both".to_string(),
1502			unpack_ipv4: false,
1503		}
1504	}
1505	/// Documentation for `ipv4_only`
1506	///
1507	pub fn ipv4_only() -> Self {
1508		Self {
1509			base: BaseField::new(),
1510			protocol: "IPv4".to_string(),
1511			unpack_ipv4: false,
1512		}
1513	}
1514	/// Documentation for `ipv6_only`
1515	///
1516	pub fn ipv6_only() -> Self {
1517		Self {
1518			base: BaseField::new(),
1519			protocol: "IPv6".to_string(),
1520			unpack_ipv4: false,
1521		}
1522	}
1523}
1524
1525impl Field for GenericIPAddressField {
1526	fn deconstruct(&self) -> FieldDeconstruction {
1527		let mut kwargs = self.base.get_kwargs();
1528
1529		// Only include non-default values
1530		if self.protocol != "both" {
1531			kwargs.insert(
1532				"protocol".to_string(),
1533				FieldKwarg::String(self.protocol.clone()),
1534			);
1535		}
1536		if self.unpack_ipv4 {
1537			kwargs.insert("unpack_ipv4".to_string(), FieldKwarg::Bool(true));
1538		}
1539
1540		FieldDeconstruction {
1541			name: self.base.name.clone(),
1542			path: "reinhardt.orm.models.GenericIPAddressField".to_string(),
1543			args: vec![],
1544			kwargs,
1545		}
1546	}
1547
1548	fn set_attributes_from_name(&mut self, name: &str) {
1549		self.base.name = Some(name.to_string());
1550	}
1551
1552	fn name(&self) -> Option<&str> {
1553		self.base.name.as_deref()
1554	}
1555}
1556
1557/// FilePathField - field for selecting file paths
1558#[derive(Debug, Clone)]
1559pub struct FilePathField {
1560	/// The base.
1561	pub base: BaseField,
1562	/// The path.
1563	pub path: String,
1564	/// The match pattern.
1565	pub match_pattern: Option<String>,
1566	/// The recursive.
1567	pub recursive: bool,
1568	/// The allow files.
1569	pub allow_files: bool,
1570	/// The allow folders.
1571	pub allow_folders: bool,
1572	/// The max length.
1573	pub max_length: u64,
1574}
1575
1576impl FilePathField {
1577	/// Create a new FilePathField for selecting filesystem paths
1578	///
1579	/// # Examples
1580	///
1581	/// ```
1582	/// use reinhardt_db::orm::fields::FilePathField;
1583	///
1584	/// let field = FilePathField::new("/var/www/uploads".to_string());
1585	/// assert_eq!(field.path, "/var/www/uploads");
1586	/// assert!(field.allow_files); // Files are allowed by default
1587	/// assert!(!field.allow_folders); // Folders are not allowed by default
1588	/// assert!(!field.recursive); // Non-recursive by default
1589	/// assert_eq!(field.max_length, 100); // Django's default
1590	/// ```
1591	pub fn new(path: String) -> Self {
1592		Self {
1593			base: BaseField::new(),
1594			path,
1595			match_pattern: None,
1596			recursive: false,
1597			allow_files: true,
1598			allow_folders: false,
1599			max_length: 100,
1600		}
1601	}
1602}
1603
1604impl Field for FilePathField {
1605	fn deconstruct(&self) -> FieldDeconstruction {
1606		let mut kwargs = self.base.get_kwargs();
1607
1608		kwargs.insert("path".to_string(), FieldKwarg::String(self.path.clone()));
1609
1610		if let Some(ref pattern) = self.match_pattern {
1611			kwargs.insert("match".to_string(), FieldKwarg::String(pattern.clone()));
1612		}
1613		if self.recursive {
1614			kwargs.insert("recursive".to_string(), FieldKwarg::Bool(true));
1615		}
1616		if !self.allow_files {
1617			kwargs.insert("allow_files".to_string(), FieldKwarg::Bool(false));
1618		}
1619		if self.allow_folders {
1620			kwargs.insert("allow_folders".to_string(), FieldKwarg::Bool(true));
1621		}
1622		if self.max_length != 100 {
1623			kwargs.insert("max_length".to_string(), FieldKwarg::Uint(self.max_length));
1624		}
1625
1626		FieldDeconstruction {
1627			name: self.base.name.clone(),
1628			path: "reinhardt.orm.models.FilePathField".to_string(),
1629			args: vec![],
1630			kwargs,
1631		}
1632	}
1633
1634	fn set_attributes_from_name(&mut self, name: &str) {
1635		self.base.name = Some(name.to_string());
1636	}
1637
1638	fn name(&self) -> Option<&str> {
1639		self.base.name.as_deref()
1640	}
1641}
1642
1643/// ForeignKey - Many-to-one relationship field
1644#[derive(Debug, Clone)]
1645pub struct ForeignKey {
1646	/// The base.
1647	pub base: BaseField,
1648	/// The to.
1649	pub to: String, // Related model name (e.g., "auth.Permission")
1650	/// The on delete.
1651	pub on_delete: String, // CASCADE, SET_NULL, etc.
1652	/// The related name.
1653	pub related_name: Option<String>,
1654}
1655
1656impl ForeignKey {
1657	/// Create a new ForeignKey for many-to-one relationships
1658	///
1659	/// # Examples
1660	///
1661	/// ```
1662	/// use reinhardt_db::orm::fields::ForeignKey;
1663	///
1664	/// let field = ForeignKey::new("auth.User".to_string(), "CASCADE".to_string());
1665	/// assert_eq!(field.to, "auth.User");
1666	/// assert_eq!(field.on_delete, "CASCADE");
1667	/// assert!(field.related_name.is_none());
1668	/// ```
1669	pub fn new(to: String, on_delete: String) -> Self {
1670		Self {
1671			base: BaseField::new(),
1672			to,
1673			on_delete,
1674			related_name: None,
1675		}
1676	}
1677}
1678
1679impl Field for ForeignKey {
1680	fn deconstruct(&self) -> FieldDeconstruction {
1681		let mut kwargs = self.base.get_kwargs();
1682
1683		// Convert to lowercase for consistency with Django
1684		kwargs.insert("to".to_string(), FieldKwarg::String(self.to.to_lowercase()));
1685		kwargs.insert(
1686			"on_delete".to_string(),
1687			FieldKwarg::String(self.on_delete.clone()),
1688		);
1689
1690		if let Some(ref name) = self.related_name {
1691			kwargs.insert("related_name".to_string(), FieldKwarg::String(name.clone()));
1692		}
1693
1694		FieldDeconstruction {
1695			name: self.base.name.clone(),
1696			path: "reinhardt.orm.models.ForeignKey".to_string(),
1697			args: vec![],
1698			kwargs,
1699		}
1700	}
1701
1702	fn set_attributes_from_name(&mut self, name: &str) {
1703		self.base.name = Some(name.to_string());
1704	}
1705
1706	fn name(&self) -> Option<&str> {
1707		self.base.name.as_deref()
1708	}
1709}
1710
1711/// OneToOneField - One-to-one relationship field
1712#[derive(Debug, Clone)]
1713pub struct OneToOneField {
1714	/// The base.
1715	pub base: BaseField,
1716	/// The to.
1717	pub to: String,
1718	/// The on delete.
1719	pub on_delete: String,
1720	/// The related name.
1721	pub related_name: Option<String>,
1722}
1723
1724impl OneToOneField {
1725	/// Create a new OneToOneField for one-to-one relationships
1726	///
1727	/// # Examples
1728	///
1729	/// ```
1730	/// use reinhardt_db::orm::fields::OneToOneField;
1731	///
1732	/// let field = OneToOneField::new("auth.User".to_string(), "CASCADE".to_string());
1733	/// assert_eq!(field.to, "auth.User");
1734	/// assert_eq!(field.on_delete, "CASCADE");
1735	/// assert!(field.related_name.is_none());
1736	/// ```
1737	pub fn new(to: String, on_delete: String) -> Self {
1738		Self {
1739			base: BaseField::new(),
1740			to,
1741			on_delete,
1742			related_name: None,
1743		}
1744	}
1745}
1746
1747impl Field for OneToOneField {
1748	fn deconstruct(&self) -> FieldDeconstruction {
1749		let mut kwargs = self.base.get_kwargs();
1750
1751		kwargs.insert("to".to_string(), FieldKwarg::String(self.to.to_lowercase()));
1752		kwargs.insert(
1753			"on_delete".to_string(),
1754			FieldKwarg::String(self.on_delete.clone()),
1755		);
1756
1757		if let Some(ref name) = self.related_name {
1758			kwargs.insert("related_name".to_string(), FieldKwarg::String(name.clone()));
1759		}
1760
1761		FieldDeconstruction {
1762			name: self.base.name.clone(),
1763			path: "reinhardt.orm.models.OneToOneField".to_string(),
1764			args: vec![],
1765			kwargs,
1766		}
1767	}
1768
1769	fn set_attributes_from_name(&mut self, name: &str) {
1770		self.base.name = Some(name.to_string());
1771	}
1772
1773	fn name(&self) -> Option<&str> {
1774		self.base.name.as_deref()
1775	}
1776}
1777
1778/// ManyToManyField - Many-to-many relationship field
1779#[derive(Debug, Clone)]
1780pub struct ManyToManyField {
1781	/// The base.
1782	pub base: BaseField,
1783	/// The to.
1784	pub to: String,
1785	/// The related name.
1786	pub related_name: Option<String>,
1787	/// The through.
1788	pub through: Option<String>,
1789}
1790
1791impl ManyToManyField {
1792	/// Create a new ManyToManyField for many-to-many relationships
1793	///
1794	/// # Examples
1795	///
1796	/// ```
1797	/// use reinhardt_db::orm::fields::ManyToManyField;
1798	///
1799	/// let field = ManyToManyField::new("auth.Permission".to_string());
1800	/// assert_eq!(field.to, "auth.Permission");
1801	/// assert!(field.related_name.is_none());
1802	/// assert!(field.through.is_none());
1803	/// ```
1804	pub fn new(to: String) -> Self {
1805		Self {
1806			base: BaseField::new(),
1807			to,
1808			related_name: None,
1809			through: None,
1810		}
1811	}
1812	/// Documentation for `with_related_name`
1813	pub fn with_related_name(to: String, related_name: String) -> Self {
1814		Self {
1815			base: BaseField::new(),
1816			to,
1817			related_name: Some(related_name),
1818			through: None,
1819		}
1820	}
1821}
1822
1823impl Field for ManyToManyField {
1824	fn deconstruct(&self) -> FieldDeconstruction {
1825		let mut kwargs = self.base.get_kwargs();
1826
1827		kwargs.insert("to".to_string(), FieldKwarg::String(self.to.to_lowercase()));
1828
1829		if let Some(ref name) = self.related_name {
1830			kwargs.insert("related_name".to_string(), FieldKwarg::String(name.clone()));
1831		}
1832
1833		if let Some(ref through) = self.through {
1834			kwargs.insert("through".to_string(), FieldKwarg::String(through.clone()));
1835		}
1836
1837		FieldDeconstruction {
1838			name: self.base.name.clone(),
1839			path: "reinhardt.orm.models.ManyToManyField".to_string(),
1840			args: vec![],
1841			kwargs,
1842		}
1843	}
1844
1845	fn set_attributes_from_name(&mut self, name: &str) {
1846		self.base.name = Some(name.to_string());
1847	}
1848
1849	fn name(&self) -> Option<&str> {
1850		self.base.name.as_deref()
1851	}
1852}
1853
1854#[cfg(test)]
1855mod tests {
1856	use super::*;
1857
1858	#[test]
1859	fn test_auto_field_deconstruct() {
1860		let mut field = AutoField::new();
1861		field.set_attributes_from_name("id");
1862		let dec = field.deconstruct();
1863
1864		assert_eq!(dec.name, Some("id".to_string()));
1865		assert_eq!(dec.path, "reinhardt.orm.models.AutoField");
1866		assert_eq!(dec.args.len(), 0);
1867		assert_eq!(dec.kwargs.get("primary_key"), Some(&FieldKwarg::Bool(true)));
1868	}
1869
1870	#[test]
1871	fn test_big_integer_field_deconstruct() {
1872		let field = BigIntegerField::new();
1873		let dec = field.deconstruct();
1874
1875		assert_eq!(dec.path, "reinhardt.orm.models.BigIntegerField");
1876		assert_eq!(dec.args.len(), 0);
1877		assert!(dec.kwargs.is_empty());
1878	}
1879
1880	#[test]
1881	fn test_boolean_field_deconstruct() {
1882		let field = BooleanField::new();
1883		let dec = field.deconstruct();
1884
1885		assert_eq!(dec.path, "reinhardt.orm.models.BooleanField");
1886		assert!(dec.kwargs.is_empty());
1887
1888		let field_with_default = BooleanField::with_default(true);
1889		let dec2 = field_with_default.deconstruct();
1890		assert_eq!(dec2.kwargs.get("default"), Some(&FieldKwarg::Bool(true)));
1891	}
1892
1893	#[test]
1894	fn test_char_field_deconstruct() {
1895		let field = CharField::new(65);
1896		let dec = field.deconstruct();
1897
1898		assert_eq!(dec.path, "reinhardt.orm.models.CharField");
1899		assert_eq!(dec.kwargs.get("max_length"), Some(&FieldKwarg::Uint(65)));
1900
1901		let field2 = CharField::with_null_blank(65);
1902		let dec2 = field2.deconstruct();
1903		assert_eq!(dec2.kwargs.get("null"), Some(&FieldKwarg::Bool(true)));
1904		assert_eq!(dec2.kwargs.get("blank"), Some(&FieldKwarg::Bool(true)));
1905	}
1906
1907	#[test]
1908	fn test_char_field_choices() {
1909		let choices = vec![
1910			("A".to_string(), "One".to_string()),
1911			("B".to_string(), "Two".to_string()),
1912		];
1913		let field = CharField::with_choices(1, choices.clone());
1914		let dec = field.deconstruct();
1915
1916		assert_eq!(
1917			dec.kwargs.get("choices"),
1918			Some(&FieldKwarg::Choices(choices))
1919		);
1920		assert_eq!(dec.kwargs.get("max_length"), Some(&FieldKwarg::Uint(1)));
1921	}
1922
1923	#[test]
1924	fn test_date_field_deconstruct() {
1925		let field = DateField::new();
1926		let dec = field.deconstruct();
1927		assert_eq!(dec.path, "reinhardt.orm.models.DateField");
1928		assert!(dec.kwargs.is_empty());
1929
1930		let field2 = DateField::with_auto_now();
1931		let dec2 = field2.deconstruct();
1932		assert_eq!(dec2.kwargs.get("auto_now"), Some(&FieldKwarg::Bool(true)));
1933	}
1934
1935	#[test]
1936	fn test_datetime_field_deconstruct() {
1937		let field = DateTimeField::new();
1938		let dec = field.deconstruct();
1939		assert!(dec.kwargs.is_empty());
1940
1941		let field2 = DateTimeField::with_auto_now_add();
1942		let dec2 = field2.deconstruct();
1943		assert_eq!(
1944			dec2.kwargs.get("auto_now_add"),
1945			Some(&FieldKwarg::Bool(true))
1946		);
1947
1948		let field3 = DateTimeField::with_both();
1949		let dec3 = field3.deconstruct();
1950		assert_eq!(dec3.kwargs.get("auto_now"), Some(&FieldKwarg::Bool(true)));
1951		assert_eq!(
1952			dec3.kwargs.get("auto_now_add"),
1953			Some(&FieldKwarg::Bool(true))
1954		);
1955	}
1956
1957	#[test]
1958	fn test_decimal_field_deconstruct() {
1959		let field = DecimalField::new(5, 2);
1960		let dec = field.deconstruct();
1961
1962		assert_eq!(dec.path, "reinhardt.orm.models.DecimalField");
1963		assert_eq!(dec.kwargs.get("max_digits"), Some(&FieldKwarg::Uint(5)));
1964		assert_eq!(dec.kwargs.get("decimal_places"), Some(&FieldKwarg::Uint(2)));
1965	}
1966
1967	#[test]
1968	fn test_email_field_deconstruct() {
1969		let field = EmailField::new();
1970		let dec = field.deconstruct();
1971
1972		assert_eq!(dec.path, "reinhardt.orm.models.EmailField");
1973		assert_eq!(dec.kwargs.get("max_length"), Some(&FieldKwarg::Uint(254)));
1974
1975		let field2 = EmailField::with_max_length(255);
1976		let dec2 = field2.deconstruct();
1977		assert_eq!(dec2.kwargs.get("max_length"), Some(&FieldKwarg::Uint(255)));
1978	}
1979}