1use crate::orm::model::Model;
63use crate::orm::registry::registry;
64use serde::{Deserialize, Serialize};
65use std::any::TypeId;
66use std::collections::HashMap;
67use std::fmt;
68
69#[non_exhaustive]
71#[derive(Debug, Clone, PartialEq)]
72pub enum ReflectionError {
73 ModelNotFound(String),
75 FieldNotFound(String),
77 TypeMismatch {
79 expected: String,
81 actual: String,
83 },
84 InvalidOperation(String),
86 SerializationError(String),
88}
89
90impl fmt::Display for ReflectionError {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 match self {
93 ReflectionError::ModelNotFound(name) => write!(f, "Model not found: {}", name),
94 ReflectionError::FieldNotFound(name) => write!(f, "Field not found: {}", name),
95 ReflectionError::TypeMismatch { expected, actual } => {
96 write!(f, "Type mismatch: expected {}, got {}", expected, actual)
97 }
98 ReflectionError::InvalidOperation(msg) => write!(f, "Invalid operation: {}", msg),
99 ReflectionError::SerializationError(msg) => {
100 write!(f, "Serialization error: {}", msg)
101 }
102 }
103 }
104}
105
106impl std::error::Error for ReflectionError {}
107
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
110#[serde(untagged)]
111pub enum FieldValue {
112 Null,
114 Bool(bool),
116 Int(i64),
118 Float(f64),
120 String(String),
122 Bytes(Vec<u8>),
124 Array(Vec<FieldValue>),
126 Object(HashMap<String, FieldValue>),
128}
129
130impl FieldValue {
131 pub fn is_null(&self) -> bool {
145 matches!(self, FieldValue::Null)
146 }
147
148 pub fn as_i64(&self) -> Option<i64> {
162 match self {
163 FieldValue::Int(v) => Some(*v),
164 _ => None,
165 }
166 }
167
168 pub fn as_f64(&self) -> Option<f64> {
170 match self {
171 FieldValue::Float(v) => Some(*v),
172 FieldValue::Int(v) => Some(*v as f64),
173 _ => None,
174 }
175 }
176
177 pub fn as_str(&self) -> Option<&str> {
179 match self {
180 FieldValue::String(s) => Some(s),
181 _ => None,
182 }
183 }
184
185 pub fn as_bool(&self) -> Option<bool> {
187 match self {
188 FieldValue::Bool(b) => Some(*b),
189 _ => None,
190 }
191 }
192}
193
194impl From<i64> for FieldValue {
195 fn from(value: i64) -> Self {
196 FieldValue::Int(value)
197 }
198}
199
200impl From<i32> for FieldValue {
201 fn from(value: i32) -> Self {
202 FieldValue::Int(value as i64)
203 }
204}
205
206impl From<f64> for FieldValue {
207 fn from(value: f64) -> Self {
208 FieldValue::Float(value)
209 }
210}
211
212impl From<bool> for FieldValue {
213 fn from(value: bool) -> Self {
214 FieldValue::Bool(value)
215 }
216}
217
218impl From<String> for FieldValue {
219 fn from(value: String) -> Self {
220 FieldValue::String(value)
221 }
222}
223
224impl From<&str> for FieldValue {
225 fn from(value: &str) -> Self {
226 FieldValue::String(value.to_owned())
227 }
228}
229
230#[derive(Debug, Clone, PartialEq)]
232pub struct FieldInfo {
233 pub name: String,
235 pub column_name: String,
237 pub field_type: String,
239 pub nullable: bool,
241}
242
243impl FieldInfo {
244 pub fn new(
246 name: impl Into<String>,
247 column_name: impl Into<String>,
248 field_type: impl Into<String>,
249 nullable: bool,
250 ) -> Self {
251 Self {
252 name: name.into(),
253 column_name: column_name.into(),
254 field_type: field_type.into(),
255 nullable,
256 }
257 }
258}
259
260#[derive(Clone)]
311pub struct ModelReflector {
312 model_name: String,
314 table_name: String,
316 #[allow(dead_code)]
319 type_id: TypeId,
320}
321
322impl ModelReflector {
323 pub fn for_model<M: Model + 'static>() -> Self {
370 Self {
371 model_name: std::any::type_name::<M>()
372 .split("::")
373 .last()
374 .unwrap_or("Unknown")
375 .to_owned(),
376 table_name: M::table_name().to_owned(),
377 type_id: TypeId::of::<M>(),
378 }
379 }
380
381 pub fn new(model_name: impl Into<String>) -> Result<Self, ReflectionError> {
385 let model_name = model_name.into();
386 let mapper = registry()
387 .get(&model_name)
388 .ok_or_else(|| ReflectionError::ModelNotFound(model_name.clone()))?;
389
390 Ok(Self {
391 table_name: mapper.table_name,
392 model_name,
393 type_id: TypeId::of::<()>(), })
395 }
396
397 pub fn model_name(&self) -> &str {
399 &self.model_name
400 }
401
402 pub fn table_name(&self) -> &str {
404 &self.table_name
405 }
406
407 pub fn field_names(&self) -> Vec<String> {
431 registry()
432 .get(&self.model_name)
433 .map(|mapper| {
434 mapper
435 .columns
436 .iter()
437 .map(|col| col.property_name.clone())
438 .collect()
439 })
440 .unwrap_or_default()
441 }
442
443 pub fn fields(&self) -> Vec<FieldInfo> {
445 registry()
446 .get(&self.model_name)
447 .map(|mapper| {
448 mapper
449 .columns
450 .iter()
451 .map(|col| {
452 FieldInfo::new(
453 &col.property_name,
454 &col.column_name,
455 &col.column_type,
456 col.nullable,
457 )
458 })
459 .collect()
460 })
461 .unwrap_or_default()
462 }
463
464 pub fn field_info(&self, field_name: &str) -> Option<FieldInfo> {
466 registry().get(&self.model_name).and_then(|mapper| {
467 mapper
468 .columns
469 .iter()
470 .find(|col| col.property_name == field_name)
471 .map(|col| {
472 FieldInfo::new(
473 &col.property_name,
474 &col.column_name,
475 &col.column_type,
476 col.nullable,
477 )
478 })
479 })
480 }
481
482 pub fn primary_key_fields(&self) -> Vec<String> {
484 registry()
485 .get(&self.model_name)
486 .map(|mapper| mapper.primary_key.clone())
487 .unwrap_or_default()
488 }
489
490 pub fn serialize_to_map<M: Model + Serialize>(
492 &self,
493 instance: &M,
494 ) -> Result<HashMap<String, FieldValue>, ReflectionError> {
495 let json_value = serde_json::to_value(instance)
496 .map_err(|e| ReflectionError::SerializationError(e.to_string()))?;
497
498 match json_value {
499 serde_json::Value::Object(map) => {
500 let mut result = HashMap::new();
501 for (key, value) in map {
502 result.insert(key, json_value_to_field_value(value));
503 }
504 Ok(result)
505 }
506 _ => Err(ReflectionError::SerializationError(
507 "Expected object".to_owned(),
508 )),
509 }
510 }
511
512 pub fn get_field_value<M: Model + Serialize>(
514 &self,
515 instance: &M,
516 field_name: &str,
517 ) -> Result<FieldValue, ReflectionError> {
518 let map = self.serialize_to_map(instance)?;
519 map.get(field_name)
520 .cloned()
521 .ok_or_else(|| ReflectionError::FieldNotFound(field_name.to_owned()))
522 }
523}
524
525impl fmt::Debug for ModelReflector {
526 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
527 f.debug_struct("ModelReflector")
528 .field("model_name", &self.model_name)
529 .field("table_name", &self.table_name)
530 .finish()
531 }
532}
533
534fn json_value_to_field_value(value: serde_json::Value) -> FieldValue {
536 match value {
537 serde_json::Value::Null => FieldValue::Null,
538 serde_json::Value::Bool(b) => FieldValue::Bool(b),
539 serde_json::Value::Number(n) => {
540 if let Some(i) = n.as_i64() {
541 FieldValue::Int(i)
542 } else if let Some(f) = n.as_f64() {
543 FieldValue::Float(f)
544 } else {
545 FieldValue::Null
546 }
547 }
548 serde_json::Value::String(s) => FieldValue::String(s),
549 serde_json::Value::Array(arr) => {
550 FieldValue::Array(arr.into_iter().map(json_value_to_field_value).collect())
551 }
552 serde_json::Value::Object(obj) => FieldValue::Object(
553 obj.into_iter()
554 .map(|(k, v)| (k, json_value_to_field_value(v)))
555 .collect(),
556 ),
557 }
558}
559
560#[cfg(test)]
561mod tests {
562 use super::*;
563 use crate::orm::Manager;
564 use crate::orm::model::Model;
565 use crate::orm::registry::{ColumnMapping, EntityMapper, registry};
566 use serial_test::serial;
567
568 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
569 struct TestUser {
570 id: Option<i64>,
571 name: String,
572 age: i32,
573 email: Option<String>,
574 }
575
576 #[derive(Debug, Clone)]
577 struct TestUserFields;
578
579 impl crate::orm::model::FieldSelector for TestUserFields {
580 fn with_alias(self, _alias: &str) -> Self {
581 self
582 }
583 }
584
585 impl Model for TestUser {
586 type PrimaryKey = i64;
587 type Fields = TestUserFields;
588 type Objects = Manager<Self>;
589
590 fn table_name() -> &'static str {
591 "test_users"
592 }
593
594 fn primary_key(&self) -> Option<Self::PrimaryKey> {
595 self.id
596 }
597
598 fn set_primary_key(&mut self, value: Self::PrimaryKey) {
599 self.id = Some(value);
600 }
601
602 fn primary_key_field() -> &'static str {
603 "id"
604 }
605
606 fn new_fields() -> Self::Fields {
607 TestUserFields
608 }
609 }
610
611 fn setup_test_registry() {
612 registry().clear();
613 let mut mapper = EntityMapper::new("test_users");
614 mapper.add_column(ColumnMapping::new("id", "id", "INTEGER").not_null());
615 mapper.add_column(ColumnMapping::new("name", "name", "VARCHAR").not_null());
616 mapper.add_column(ColumnMapping::new("age", "age", "INTEGER").not_null());
617 mapper.add_column(ColumnMapping::new("email", "email", "VARCHAR"));
618 mapper.set_primary_key(vec!["id".to_owned()]);
619 registry().register("TestUser", mapper);
620 }
621
622 #[test]
623 fn test_model_reflector_for_model() {
624 let reflector = ModelReflector::for_model::<TestUser>();
625 assert_eq!(reflector.table_name(), "test_users");
626 assert!(reflector.model_name().contains("TestUser"));
627 }
628
629 #[test]
630 #[serial]
631 fn test_model_reflector_new() {
632 setup_test_registry();
633 let reflector = ModelReflector::new("TestUser").unwrap();
634 assert_eq!(reflector.model_name(), "TestUser");
635 assert_eq!(reflector.table_name(), "test_users");
636 }
637
638 #[test]
639 #[serial]
640 fn test_model_reflector_new_not_found() {
641 registry().clear();
642 let result = ModelReflector::new("NonExistent");
643 assert!(result.is_err());
644 assert!(matches!(
645 result.unwrap_err(),
646 ReflectionError::ModelNotFound(_)
647 ));
648 }
649
650 #[test]
651 #[serial]
652 fn test_model_reflector_field_names() {
653 setup_test_registry();
654 let reflector = ModelReflector::new("TestUser").unwrap();
655 let field_names = reflector.field_names();
656 assert_eq!(field_names.len(), 4);
657 assert!(field_names.contains(&"id".to_owned()));
658 assert!(field_names.contains(&"name".to_owned()));
659 assert!(field_names.contains(&"age".to_owned()));
660 assert!(field_names.contains(&"email".to_owned()));
661 }
662
663 #[test]
664 #[serial]
665 fn test_model_reflector_fields() {
666 setup_test_registry();
667 let reflector = ModelReflector::new("TestUser").unwrap();
668 let fields = reflector.fields();
669 assert_eq!(fields.len(), 4);
670
671 let id_field = fields.iter().find(|f| f.name == "id").unwrap();
672 assert_eq!(id_field.column_name, "id");
673 assert_eq!(id_field.field_type, "INTEGER");
674 assert!(!id_field.nullable);
675 }
676
677 #[test]
678 #[serial]
679 fn test_model_reflector_field_info() {
680 setup_test_registry();
681 let reflector = ModelReflector::new("TestUser").unwrap();
682
683 let name_field = reflector.field_info("name").unwrap();
684 assert_eq!(name_field.name, "name");
685 assert_eq!(name_field.column_name, "name");
686 assert_eq!(name_field.field_type, "VARCHAR");
687 assert!(!name_field.nullable);
688
689 let email_field = reflector.field_info("email").unwrap();
690 assert!(email_field.nullable);
691
692 let nonexistent = reflector.field_info("nonexistent");
693 assert!(nonexistent.is_none());
694 }
695
696 #[test]
697 #[serial]
698 fn test_model_reflector_primary_key_fields() {
699 setup_test_registry();
700 let reflector = ModelReflector::new("TestUser").unwrap();
701 let pk_fields = reflector.primary_key_fields();
702 assert_eq!(pk_fields.len(), 1);
703 assert_eq!(pk_fields[0], "id");
704 }
705
706 #[test]
707 fn test_serialize_to_map() {
708 let reflector = ModelReflector::for_model::<TestUser>();
709 let user = TestUser {
710 id: Some(1),
711 name: "Alice".to_owned(),
712 age: 30,
713 email: Some("alice@example.com".to_owned()),
714 };
715
716 let map = reflector.serialize_to_map(&user).unwrap();
717 assert_eq!(map.get("id").unwrap().as_i64(), Some(1));
718 assert_eq!(map.get("name").unwrap().as_str(), Some("Alice"));
719 assert_eq!(map.get("age").unwrap().as_i64(), Some(30));
720 assert_eq!(
721 map.get("email").unwrap().as_str(),
722 Some("alice@example.com")
723 );
724 }
725
726 #[test]
727 fn test_get_field_value() {
728 let reflector = ModelReflector::for_model::<TestUser>();
729 let user = TestUser {
730 id: Some(42),
731 name: "Bob".to_owned(),
732 age: 25,
733 email: None,
734 };
735
736 let id_value = reflector.get_field_value(&user, "id").unwrap();
737 assert_eq!(id_value.as_i64(), Some(42));
738
739 let name_value = reflector.get_field_value(&user, "name").unwrap();
740 assert_eq!(name_value.as_str(), Some("Bob"));
741
742 let age_value = reflector.get_field_value(&user, "age").unwrap();
743 assert_eq!(age_value.as_i64(), Some(25));
744
745 let email_value = reflector.get_field_value(&user, "email").unwrap();
746 assert!(email_value.is_null());
747 }
748
749 #[test]
750 fn test_field_value_conversions() {
751 let int_value = FieldValue::Int(42);
752 assert_eq!(int_value.as_i64(), Some(42));
753 assert_eq!(int_value.as_f64(), Some(42.0));
754 assert_eq!(int_value.as_str(), None);
755 assert_eq!(int_value.as_bool(), None);
756
757 let float_value = FieldValue::Float(3.15);
758 assert_eq!(float_value.as_i64(), None);
759 assert_eq!(float_value.as_f64(), Some(3.15));
760
761 let string_value = FieldValue::String("hello".to_owned());
762 assert_eq!(string_value.as_str(), Some("hello"));
763 assert_eq!(string_value.as_i64(), None);
764
765 let bool_value = FieldValue::Bool(true);
766 assert_eq!(bool_value.as_bool(), Some(true));
767
768 let null_value = FieldValue::Null;
769 assert!(null_value.is_null());
770 }
771
772 #[test]
773 fn test_field_value_from_conversions() {
774 let int_value: FieldValue = 42i32.into();
775 assert_eq!(int_value.as_i64(), Some(42));
776
777 let i64_value: FieldValue = 100i64.into();
778 assert_eq!(i64_value.as_i64(), Some(100));
779
780 let float_value: FieldValue = 3.15f64.into();
781 assert_eq!(float_value.as_f64(), Some(3.15));
782
783 let bool_value: FieldValue = true.into();
784 assert_eq!(bool_value.as_bool(), Some(true));
785
786 let string_value: FieldValue = "test".into();
787 assert_eq!(string_value.as_str(), Some("test"));
788
789 let owned_string_value: FieldValue = "test".to_owned().into();
790 assert_eq!(owned_string_value.as_str(), Some("test"));
791 }
792
793 #[test]
794 fn test_field_info_new() {
795 let field = FieldInfo::new("username", "user_name", "VARCHAR", false);
796 assert_eq!(field.name, "username");
797 assert_eq!(field.column_name, "user_name");
798 assert_eq!(field.field_type, "VARCHAR");
799 assert!(!field.nullable);
800 }
801
802 #[test]
803 fn test_reflection_error_display() {
804 let err1 = ReflectionError::ModelNotFound("User".to_owned());
805 assert_eq!(err1.to_string(), "Model not found: User");
806
807 let err2 = ReflectionError::FieldNotFound("name".to_owned());
808 assert_eq!(err2.to_string(), "Field not found: name");
809
810 let err3 = ReflectionError::TypeMismatch {
811 expected: "String".to_owned(),
812 actual: "Int".to_owned(),
813 };
814 assert_eq!(err3.to_string(), "Type mismatch: expected String, got Int");
815
816 let err4 = ReflectionError::InvalidOperation("test".to_owned());
817 assert_eq!(err4.to_string(), "Invalid operation: test");
818
819 let err5 = ReflectionError::SerializationError("test".to_owned());
820 assert_eq!(err5.to_string(), "Serialization error: test");
821 }
822}