Implement Associated Type for Keys #3
| @ -350,11 +350,28 @@ pub mod repository { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub trait PrimaryKeyType { | ||||||
|  |         fn key_as_string(&self) -> String; | ||||||
|  |         fn key_from_string(&self, s: String) -> Self; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     impl PrimaryKeyType for i64 { | ||||||
|  |         fn key_as_string(&self) -> String { | ||||||
|  |             self.to_string() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fn key_from_string(&self, s: String) -> Self { | ||||||
|  |             s.parse::<usize>().unwrap() as i64 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     #[async_trait] |     #[async_trait] | ||||||
|     pub trait AdminRepository: Send + Sync { |     pub trait AdminRepository: Send + Sync { | ||||||
|  |         type Key: PrimaryKeyType; | ||||||
|  | 
 | ||||||
|         async fn info(&self, context: &RepositoryContext) -> RepositoryInfo; |         async fn info(&self, context: &RepositoryContext) -> RepositoryInfo; | ||||||
|         async fn list(&self, context: &RepositoryContext) -> RepositoryList; |         async fn list(&self, context: &RepositoryContext) -> RepositoryList; | ||||||
|         async fn get(&self, context: &RepositoryContext, id: LookupKey) -> Option<RepositoryItem>; |         async fn get(&self, context: &RepositoryContext, id: Self::Key) -> Option<RepositoryItem>; | ||||||
|         async fn create( |         async fn create( | ||||||
|             &mut self, |             &mut self, | ||||||
|             context: &RepositoryContext, |             context: &RepositoryContext, | ||||||
| @ -363,15 +380,76 @@ pub mod repository { | |||||||
|         async fn update( |         async fn update( | ||||||
|             &mut self, |             &mut self, | ||||||
|             context: &RepositoryContext, |             context: &RepositoryContext, | ||||||
|             id: LookupKey, |             id: Self::Key, | ||||||
|             data: Value, |             data: Value, | ||||||
|         ) -> Option<RepositoryItem>; |         ) -> Option<RepositoryItem>; | ||||||
|         async fn replace( |         async fn replace( | ||||||
|             &mut self, |             &mut self, | ||||||
|             context: &RepositoryContext, |             context: &RepositoryContext, | ||||||
|             id: LookupKey, |             id: Self::Key, | ||||||
|             data: Value, |             data: Value, | ||||||
|         ) -> Option<RepositoryItem>; |         ) -> Option<RepositoryItem>; | ||||||
|         async fn delete(&mut self, context: &RepositoryContext, id: LookupKey) -> Option<Value>; |         async fn delete(&mut self, context: &RepositoryContext, id: Self::Key) -> Option<Value>; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     use std::any::Any; | ||||||
|  | 
 | ||||||
|  |     trait Key: Any { | ||||||
|  |         fn as_any(&self) -> &dyn Any; | ||||||
|  |         fn from_str(s: &str) -> Self | ||||||
|  |         where | ||||||
|  |             Self: Sized; | ||||||
|  |         fn to_string(&self) -> String; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     impl<T: Any> Key for T { | ||||||
|  |         fn as_any(&self) -> &dyn Any { | ||||||
|  |             self | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     impl Key for String { | ||||||
|  |         fn from_str(s: &str) -> Self { | ||||||
|  |             s.to_string() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fn to_string(&self) -> String { | ||||||
|  |             self.clone() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     impl Key for i64 { | ||||||
|  |         fn from_str(s: &str) -> Self { | ||||||
|  |             s.parse().expect("Invalid i64 string") | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fn to_string(&self) -> String { | ||||||
|  |             self.to_string() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[async_trait] | ||||||
|  |     pub trait ErasedAdminRepository: Send + Sync { | ||||||
|  |         async fn info(&self, context: &RepositoryContext) -> RepositoryInfo; | ||||||
|  |         async fn list(&self, context: &RepositoryContext) -> RepositoryList; | ||||||
|  |         async fn get(&self, context: &RepositoryContext, id: &dyn Key) -> Option<RepositoryItem>; | ||||||
|  |         async fn create( | ||||||
|  |             &mut self, | ||||||
|  |             context: &RepositoryContext, | ||||||
|  |             data: Value, | ||||||
|  |         ) -> Option<RepositoryItem>; | ||||||
|  |         async fn update( | ||||||
|  |             &mut self, | ||||||
|  |             context: &RepositoryContext, | ||||||
|  |             id: &dyn Key, | ||||||
|  |             data: Value, | ||||||
|  |         ) -> Option<RepositoryItem>; | ||||||
|  |         async fn replace( | ||||||
|  |             &mut self, | ||||||
|  |             context: &RepositoryContext, | ||||||
|  |             id: &dyn Key, | ||||||
|  |             data: Value, | ||||||
|  |         ) -> Option<RepositoryItem>; | ||||||
|  |         async fn delete(&mut self, context: &RepositoryContext, id: &dyn Key) -> Option<Value>; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										37
									
								
								src/bin/generic_trait_type_erasure.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/bin/generic_trait_type_erasure.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | pub trait Repository { | ||||||
|  |     type Key; | ||||||
|  | 
 | ||||||
|  |     fn get_data(&self, key: Self::Key) -> String; | ||||||
|  |     fn set_data(&self, key: Self::Key, value: String); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | use std::any::Any; | ||||||
|  | 
 | ||||||
|  | trait Key: Any { | ||||||
|  |     fn as_any(&self) -> &dyn Any; | ||||||
|  |     fn from_str(s: &str) -> Self where Self: Sized; | ||||||
|  |     fn to_string(&self) -> String; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T: Any> Key for T { | ||||||
|  |     fn as_any(&self) -> &dyn Any { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Key for String { | ||||||
|  |     fn from_str(s: &str) -> Self { | ||||||
|  |         s.to_string() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn to_string(&self) -> String { | ||||||
|  |         self.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub trait RepositoryTypeErased { | ||||||
|  |     fn get_data(&self, key: Key) -> String; | ||||||
|  |     fn set_data(&self, key: Key, value: String); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user