random ud
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| /target | ||||
							
								
								
									
										1229
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1229
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										14
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| [package] | ||||
| name = "http_core" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| description = "Core traits and types for building API clients with http_derive" | ||||
| license = "MIT OR Apache-2.0" | ||||
|  | ||||
| [dependencies] | ||||
| async-trait = "0.1" | ||||
| awc = "3"  | ||||
| serde = { version = "1", features = ["derive"] }  | ||||
| toml = "0.9.5" | ||||
| urlencoding = "2"  | ||||
|  | ||||
							
								
								
									
										114
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | ||||
| use async_trait::async_trait; | ||||
| use serde::{ Deserialize, Serialize }; | ||||
| use std::collections::HashMap; | ||||
| use std::path::Path; | ||||
| use std::fs; | ||||
|  | ||||
| /// A trait every API request type should implement (via macro). | ||||
| /// Provides info about the HTTP protocol, URLs, and supported methods. | ||||
| pub trait HasHttp { | ||||
|     /// Methods this request supports (GET, POST, etc.) | ||||
|     fn http_methods() -> &'static [&'static str]; | ||||
|  | ||||
|     /// Production endpoint (base URL). | ||||
|     fn live_url() -> &'static str; | ||||
|  | ||||
|     /// Sandbox endpoint (base URL). | ||||
|     fn sandbox_url() -> &'static str; | ||||
| } | ||||
|  | ||||
| /// Trait implemented by all request types that can be sent to an HTTP API. | ||||
| /// Usually derived via `#[derive(HttpRequest)]`. | ||||
| #[async_trait] | ||||
| pub trait Queryable: HasHttp + Send + Sync { | ||||
|     /// The response type for this query. | ||||
|     type R; | ||||
|     /// The error type for this query. | ||||
|     type E: std::error::Error + Send + Sync + 'static; | ||||
|  | ||||
|     /// Send the query, with flexibility for environment and overrides. | ||||
|     /// | ||||
|     /// - `override_url`: if `Some`, use this instead of live/sandbox. | ||||
|     /// - `sandbox`: if true, use sandbox_url. | ||||
|     /// - `method_override`: optional HTTP method override (GET, POST, etc.). | ||||
|     /// - `headers`: optional headers. | ||||
|     async fn send( | ||||
|         &self, | ||||
|         override_url: Option<&str>, | ||||
|         sandbox: bool, | ||||
|         method_override: Option<&str>, | ||||
|         headers: Option<Vec<(&str, &str)>>, | ||||
|     ) -> Result<Self::R, Self::E>; | ||||
| } | ||||
|  | ||||
| /// Trait for dispatching API calls in bulk or single-shot mode. | ||||
| /// | ||||
| /// Implemented automatically for generated enums by the `#[api_dispatch]` macro. | ||||
| #[async_trait] | ||||
| pub trait ApiDispatch { | ||||
|     /// Send all queries represented by this enum variant. | ||||
|     /// | ||||
|     /// - `client`: A preconfigured `awc::Client` | ||||
|     /// - `keys`: A shared API key store (depends on your app crate) | ||||
|     async fn send_all( | ||||
|         &self, | ||||
|         client: &awc::Client, | ||||
|         keys: &HashMap<String, crate::Keys>, // ⚠️ placeholder, you may need to re-export Keys | ||||
|         override_url: Option<&str>, | ||||
|         sandbox: bool, | ||||
|         method_override: Option<&str>, | ||||
|     ) -> Result<(), Box<dyn std::error::Error + Send + Sync>>; | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Deserialize, Serialize)] | ||||
| pub struct Key { | ||||
|     pub key: String, | ||||
|     pub secret: String, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Deserialize, Serialize)] | ||||
| pub struct Keys { | ||||
|     pub keys: HashMap<String, Key>, | ||||
| } | ||||
|  | ||||
| impl Keys { | ||||
|     /// Convenience method to get a key by name (e.g. "alpaca") | ||||
|     pub fn get(&self, name: &str) -> Option<&Key> { | ||||
|         self.keys.get(name) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Loads API keys from ~/.config/keys or fallback ./keys directory. | ||||
| /// Each `.toml` file should contain a `Key { key, secret }` struct. | ||||
| /// The filename (without `.toml`) becomes the key name in the map. | ||||
| pub fn load_api_keys() -> Result<Keys, Box<dyn std::error::Error>> { | ||||
|     let home_dir = std::env::var("HOME")?; | ||||
|     let config_dir = Path::new(&home_dir).join(".config/keys"); | ||||
|     let fallback_dir = Path::new("keys"); | ||||
|  | ||||
|     let dir_path = if config_dir.exists() { | ||||
|         config_dir | ||||
|     } else { | ||||
|         fallback_dir.to_path_buf() | ||||
|     }; | ||||
|  | ||||
|     let mut keys_map = HashMap::new(); | ||||
|  | ||||
|     for entry in fs::read_dir(dir_path)? { | ||||
|         let entry = entry?; | ||||
|         let path = entry.path(); | ||||
|  | ||||
|         if path.extension().and_then(|s| s.to_str()) == Some("toml") { | ||||
|             let contents = fs::read_to_string(&path)?; | ||||
|             let key: Key = toml::from_str(&contents)?; | ||||
|  | ||||
|             if let Some(stem) = path.file_stem().and_then(|s| s.to_str()) { | ||||
|                 keys_map.insert(stem.to_string(), key); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Ok(Keys { keys: keys_map }) | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user