├── .gitignore ├── src ├── auth.rs ├── lib.rs ├── request.rs └── maera.rs ├── libcurl-impersonate-chrome.pc ├── maera-test ├── Cargo.toml ├── src │ └── main.rs └── Cargo.lock ├── Cargo.toml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /src/auth.rs: -------------------------------------------------------------------------------- 1 | use crate::MaeraRequest; 2 | 3 | // pub type JobAuthorizer = dyn fn() -> + Send + Sync + 'static; 4 | -------------------------------------------------------------------------------- /libcurl-impersonate-chrome.pc: -------------------------------------------------------------------------------- 1 | prefix=/usr/local 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | 5 | Name: libcurl-impersonate-chrome 6 | Description: The libcurl-impersonate-chrome library 7 | Version: 1.0.0 8 | Libs: -L${libdir} -lcurl-impersonate-chrome 9 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod maera; 2 | mod request; 3 | 4 | pub use clokwerk::{AsyncJob, AsyncScheduler}; 5 | pub use maera::*; 6 | pub use ratmom::cookies; 7 | pub use ratmom::http::{Method, Request, Response, StatusCode}; 8 | pub use ratmom::AsyncBody; 9 | pub use ratmom::AsyncReadResponseExt; 10 | pub use request::{Chain, ChainableRequest, ChainableRequestBuilder}; 11 | 12 | pub use clokwerk::Interval; 13 | -------------------------------------------------------------------------------- /maera-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "maera-test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | maera = { path = ".." } 10 | async-trait = "0.1.67" 11 | tokio = { version = ">=1.26.0", features = ["full"] } 12 | serde = { version = ">=1.0.126", features = ["derive"] } 13 | serde_json = ">=1.0.59" 14 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "maera" 3 | version = "0.1.3" 4 | edition = "2021" 5 | description = "A monitor for periodically scraping websites with genuine browser fingerprints" 6 | readme = "README.md" 7 | repository = "https://github.com/xetera/maera" 8 | license = "MIT" 9 | keywords = ["scraping", "fingerprinting"] 10 | categories = ["web-programming::http-client"] 11 | 12 | [dependencies] 13 | ratmom = { git = "https://codeberg.org/transcast/ratmom.git", features = ["impersonate-chrome", "text-decoding", "cookies"], default-features = false, version = "0.1.0" } 14 | async-trait = ">=0.1.67" 15 | tokio = { version = ">=1.26.0", features = ["full"] } 16 | serde = { version = ">=1.0.126", features = ["derive"] } 17 | clokwerk = ">=0.4.0" 18 | futures-io = ">=0.3.27" 19 | futures = "0.3.27" 20 | # cron = ">=0.12.0" 21 | url = ">=2.2.2" 22 | 23 | [lib] 24 | crate-type = ["rlib"] 25 | -------------------------------------------------------------------------------- /maera-test/src/main.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | use maera::*; 3 | use serde_json::{from_str, to_string_pretty, Value}; 4 | use std::time::Duration; 5 | 6 | struct Peet; 7 | 8 | #[async_trait] 9 | impl JobHandler for Peet { 10 | type Response = MaeraResponse; 11 | fn request(&self, builder: ChainableRequestBuilder) -> Chain { 12 | builder 13 | .url("/api/all") 14 | .delay(Duration::from_secs(60)) 15 | .build() 16 | .into() 17 | } 18 | 19 | async fn on_success(&self, response: &mut Self::Response) -> Decision { 20 | // get JSON from response text 21 | let body = response.text().await.unwrap(); 22 | let json = from_str::(&body).unwrap(); 23 | println!("{}", to_string_pretty(&json).unwrap()); 24 | Decision::Continue 25 | } 26 | } 27 | 28 | #[tokio::main] 29 | async fn main() { 30 | let job = JobBuilder::new() 31 | .base_url("https://tls.peet.ws") 32 | .handler(Peet) 33 | .build(); 34 | let maera = Maera::new(vec![job]); 35 | 36 | maera.start().await.unwrap(); 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maera 2 | 3 | A simple interval-based site monitor that bypasses TLS fingerprinting on sites. 4 | 5 | ```rs 6 | use async_trait::async_trait; 7 | use maera::*; 8 | use serde_json::{from_str, to_string_pretty, Value}; 9 | use std::time::Duration; 10 | 11 | struct Peet; 12 | 13 | #[async_trait] 14 | impl JobHandler for Peet { 15 | type Response = MaeraResponse; 16 | fn request(&self, builder: ChainableRequestBuilder) -> Chain { 17 | builder 18 | .url("/api/all") 19 | .delay(Duration::from_secs(60)) 20 | .into() 21 | } 22 | async fn on_success(&self, response: &mut Self::Response) -> Decision { 23 | // get JSON from response text 24 | let body = response.text().await.unwrap(); 25 | let json = from_str::(&body).unwrap(); 26 | println!("{}", to_string_pretty(&json).unwrap()); 27 | Decision::Continue 28 | } 29 | } 30 | 31 | #[tokio::main] 32 | async fn main() { 33 | let job = JobBuilder::new() 34 | .base_url("https://tls.peet.ws") 35 | .handler(Peet) 36 | .build(); 37 | let maera = Maera::new(vec![job]); 38 | 39 | maera.start().await.unwrap(); 40 | } 41 | ``` 42 | 43 | ## Impersonating Browsers 44 | 45 | If you're experienced with systems programming, you might expect that libcurl-impersonate-chrome.so is statically linked and shipped with the library itself to have fine control over the fingerprints. However, I'm not, and I don't know how to do it! So you're expected to preload it with the following command when running your binary. 46 | 47 | Assuming your shared library lives inside `/usr/local/lib`, you can set the following env variables to preload [the required libraries](https://github.com/lwthiker/curl-impersonate/releases/latest) 48 | 49 | ``` 50 | LD_PRELOAD="/usr/local/lib/libcurl-impersonate-chrome.so" CURL_IMPERSONATE=chrome111 ./your/binary 51 | ``` 52 | 53 | It's recommended to not change the headers for the request too much as the order and values of headers are used for fingerprinting purposes, so a lot of them like `user-agent` are hardcoded. 54 | 55 | > Warning, I have no idea how to build rust libraries (as you can tell from the type signature of traits). If you run into this and want to improve the API, feel free to open a PR. 56 | 57 | ## Why Maera? 58 | 59 | She's one of the main characters in the [Destiny's Crucible series](https://www.goodreads.com/book/show/30985483-cast-under-an-alien-sun). Highly recommended read! 60 | 61 | ![Book cover](https://images-na.ssl-images-amazon.com/images/S/compressed.photo.goodreads.com/books/1468198764i/30985483.jpg) 62 | -------------------------------------------------------------------------------- /src/request.rs: -------------------------------------------------------------------------------- 1 | use ratmom::{http::Method, AsyncBody}; 2 | use std::{ 3 | marker::{Send, Sync}, 4 | time::Duration, 5 | }; 6 | 7 | use crate::MaeraResponse; 8 | 9 | /// Declarative chaining of requests 10 | // #[derive(Clone)] 11 | pub enum Chain { 12 | /// Final product 13 | End(K), 14 | Next( 15 | ChainableRequest, 16 | Box Chain + Sync + Send + 'static>, 17 | ), 18 | } 19 | 20 | impl Chain { 21 | pub fn end(k: K) -> Self { 22 | Chain::End(k) 23 | } 24 | pub fn next(request: ChainableRequest, f: F) -> Self 25 | where 26 | F: Fn(MaeraResponse) -> Chain + Sync + Send + 'static, 27 | { 28 | Chain::Next(request, Box::new(f)) 29 | } 30 | /// Executes the chain of requests 31 | pub(crate) async fn run(self, client: &ratmom::HttpClient) -> Result { 32 | let mut next = self; 33 | let mut first_run = true; 34 | loop { 35 | match next { 36 | Chain::End(k) => return Ok(k), 37 | Chain::Next(chainable, f) => { 38 | // We wanna make sure that we don't sleep on the first run 39 | if !first_run { 40 | tokio::time::sleep(chainable.delay).await; 41 | first_run = false; 42 | } 43 | let request: ratmom::http::Request = chainable.into(); 44 | let result = client.send_async(request).await?; 45 | next = f(result); 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | #[derive(Clone)] 53 | pub struct ChainableRequest { 54 | pub url: String, 55 | pub method: Method, 56 | /// Headers are all appended 57 | pub headers: Vec<(String, String)>, 58 | pub body: Option, 59 | pub delay: Duration, 60 | } 61 | 62 | impl From for Chain { 63 | fn from(k: ChainableRequestBuilder) -> Self { 64 | Chain::next(k.build(), Chain::end) 65 | } 66 | } 67 | 68 | impl From for Chain { 69 | fn from(k: ChainableRequest) -> Self { 70 | Chain::next(k, Chain::end) 71 | } 72 | } 73 | /// Helper conversion for the auth method 74 | // impl From for Chain> { 75 | // fn from(k: ChainableRequest) -> Self { 76 | // Chain::one(k) 77 | // } 78 | // } 79 | 80 | #[derive(Default)] 81 | pub struct ChainableRequestBuilder { 82 | base_url: Option, 83 | url: Option, 84 | method: Option, 85 | /// Headers are all appended 86 | headers: Vec<(String, String)>, 87 | body: Option, 88 | delay: Option, 89 | } 90 | 91 | impl ChainableRequestBuilder { 92 | pub fn new() -> Self { 93 | Self::default() 94 | } 95 | 96 | pub fn from_base_url(base_url: impl Into) -> Self { 97 | Self { 98 | base_url: Some(base_url.into()), 99 | ..Default::default() 100 | } 101 | } 102 | 103 | pub fn url(mut self, url: impl Into) -> Self { 104 | self.url = Some(format!( 105 | "{}{}", 106 | self.base_url.clone().unwrap_or_default(), 107 | url.into() 108 | )); 109 | self 110 | } 111 | 112 | pub fn method(mut self, method: Method) -> Self { 113 | self.method = Some(method); 114 | self 115 | } 116 | 117 | pub fn header(mut self, key: String, value: String) -> Self { 118 | self.headers.push((key, value)); 119 | self 120 | } 121 | 122 | pub fn body(mut self, body: String) -> Self { 123 | self.body = Some(body); 124 | self 125 | } 126 | 127 | pub fn delay(mut self, delay: Duration) -> Self { 128 | self.delay = Some(delay); 129 | self 130 | } 131 | 132 | pub fn build(self) -> ChainableRequest { 133 | ChainableRequest { 134 | url: self.url.unwrap(), 135 | method: self.method.unwrap_or(Method::GET), 136 | headers: self.headers, 137 | body: self.body, 138 | delay: self.delay.unwrap_or_default(), 139 | } 140 | } 141 | } 142 | 143 | impl From for ratmom::http::Request { 144 | fn from(req: ChainableRequest) -> Self { 145 | let mut builder = ratmom::http::Request::builder() 146 | .method(req.method) 147 | .uri(req.url); 148 | 149 | for (key, value) in req.headers { 150 | builder = builder.header(key, value); 151 | } 152 | 153 | if let Some(body) = req.body { 154 | builder.body(body.into()).unwrap() 155 | } else { 156 | builder.body(AsyncBody::empty()).unwrap() 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/maera.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | str::FromStr, 3 | sync::{atomic::AtomicU32, Arc}, 4 | }; 5 | 6 | use async_trait::async_trait; 7 | use ratmom::{ 8 | cookies::{Cookie, CookieJar}, 9 | http::Uri, 10 | AsyncBody, HttpClient, Request, Response, 11 | }; 12 | 13 | use crate::{request::Chain, ChainableRequestBuilder}; 14 | 15 | // use crate::auth::JobAuthorizer; 16 | 17 | const DEFAULT_USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"; 18 | 19 | pub type MaeraRequest = Request; 20 | pub type MaeraResponse = Response; 21 | pub type MaeraError = ratmom::Error; 22 | 23 | /// The decision process after a request is made 24 | pub enum Decision { 25 | /// Do nothing, continue scraping as usual 26 | Continue, 27 | /// Runs the authorization process immediately 28 | Authorize, 29 | /// Stops the monitor from running 30 | Stop, 31 | } 32 | 33 | pub type AuthorizeNext = Chain>; 34 | 35 | // type Authorizer = Box; 36 | 37 | #[async_trait] 38 | pub trait JobHandler: Send + Sync + 'static { 39 | type Response: Send; 40 | // fn authorize(&self) -> AuthorizeNext { 41 | // // no cookies passed up by default 42 | // Chain::End(vec![]) 43 | // } 44 | 45 | fn request(&self, builder: ChainableRequestBuilder) -> Chain; 46 | /// Called when a request is successfully made 47 | async fn on_success(&self, response: &mut Self::Response) -> Decision; 48 | /// Called when a request fails 49 | async fn on_error(&self, _error: MaeraError) -> Decision { 50 | Decision::Continue 51 | } 52 | } 53 | 54 | pub type Authorizer = Box AuthorizeNext + Send + Sync + 'static>; 55 | // pub trait Authorizer: Send + Sync + 'static { 56 | // fn authorize(&self) -> AuthorizeNext; 57 | // } 58 | 59 | pub struct Job { 60 | /// The name of the job 61 | // TODO: allow for multiple handlers under a single job 62 | pub handler: Arc, 63 | pub authorizer: Option, 64 | pub base_url: String, 65 | cookie_jar: CookieJar, 66 | #[allow(dead_code)] 67 | auth_retries: AtomicU32, 68 | } 69 | 70 | impl From> for Job { 71 | fn from(value: JobBuilder) -> Job { 72 | Job { 73 | cookie_jar: value.cookie_jar.unwrap_or_default(), 74 | base_url: value.base_url.expect("Missing base_url"), 75 | handler: Arc::new(value.handler.expect("Missing handler")), 76 | authorizer: value.authorizer, 77 | auth_retries: AtomicU32::default(), 78 | } 79 | } 80 | } 81 | 82 | pub struct JobBuilder { 83 | cookie_jar: Option, 84 | base_url: Option, 85 | handler: Option, 86 | authorizer: Option, 87 | } 88 | 89 | impl Default for JobBuilder { 90 | fn default() -> Self { 91 | Self { 92 | cookie_jar: None, 93 | base_url: None, 94 | handler: None, 95 | authorizer: None, 96 | } 97 | } 98 | } 99 | 100 | impl JobBuilder { 101 | pub fn new() -> Self { 102 | Self::default() 103 | } 104 | 105 | pub fn cookie_jar(mut self, cookie_jar: CookieJar) -> Self { 106 | self.cookie_jar = Some(cookie_jar); 107 | self 108 | } 109 | 110 | pub fn base_url(mut self, base_url: impl Into) -> Self { 111 | self.base_url = Some(base_url.into()); 112 | self 113 | } 114 | 115 | pub fn handler(mut self, handler: T) -> Self { 116 | self.handler = Some(handler); 117 | self 118 | } 119 | 120 | pub fn authorizer(mut self, authorizer: F) -> Self 121 | where 122 | F: Fn() -> AuthorizeNext + Send + Sync + 'static, 123 | { 124 | self.authorizer = Some(Box::new(authorizer)); 125 | self 126 | } 127 | 128 | pub fn build(self) -> Job { 129 | self.into() 130 | } 131 | } 132 | 133 | // pub struct RequestOptions { 134 | // } 135 | // impl Default for RequestOptions { 136 | // fn default() -> Self { 137 | // Self { method: Method::GET, append_headers: vec![] } 138 | // } 139 | // } 140 | 141 | // struct Domain { 142 | // url 143 | // } 144 | 145 | // #[derive(Clone)] 146 | // #[derive(Send)] 147 | pub struct Maera { 148 | client: Arc, 149 | pub jobs: Vec>, 150 | // pub running: Vec, 151 | } 152 | 153 | impl Maera { 154 | pub fn new(jobs: Vec>) -> Self { 155 | let client = Arc::new(ratmom::HttpClientBuilder::new().default_headers(&[ 156 | ("cache-control", "no-cache"), 157 | ("sec-ch-ua", "\"Google Chrome\";v=\"111\", \"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"111\""), 158 | ("sec-ch-ua-mobile", "?0"), 159 | ("sec-ch-ua-platform", "Windows"), 160 | // ("sec-ch-ua-platform", "macOS"), 161 | // this seems to mess with the order of the headers 162 | // ("dnt", "1"), 163 | ("Upgrade-Insecure-Requests", "1"), 164 | ("User-Agent", DEFAULT_USER_AGENT), 165 | // ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"), 166 | ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"), 167 | ("Sec-Fetch-Site", "none"), 168 | ("Sec-Fetch-Mode", "navigate"), 169 | ("Sec-Fetch-User", "?1"), 170 | ("Sec-Fetch-Dest", "document"), 171 | ("Accept-Encoding", "gzip, deflate, br"), 172 | ("Accept-Language", "en-US,en;q=0.9"), 173 | ]).build().unwrap()); 174 | Self { jobs, client } 175 | } 176 | 177 | /// Authorization function to return cookies 178 | async fn authorize(client: &HttpClient, job: &Arc>) -> Result<(), ratmom::Error> 179 | where 180 | T: JobHandler, 181 | { 182 | if let Some(ref authorize) = &job.authorizer { 183 | let cookie_chain = authorize(); 184 | let result = cookie_chain.run(client).await?; 185 | // We can just use the base url for the cookie here that should be 186 | let uri = Uri::from_str(&job.base_url).expect("invalid base url"); 187 | for cookie in result.into_iter() { 188 | // TODO: error handling hours 189 | job.cookie_jar.set(cookie, &uri).unwrap(); 190 | } 191 | } 192 | Ok(()) 193 | } 194 | 195 | async fn send_request( 196 | client: &Arc, 197 | chain: Chain, 198 | handler: &Arc, 199 | ) -> Decision 200 | where 201 | T: JobHandler, 202 | { 203 | match chain.run(client).await { 204 | Ok(mut response) => handler.on_success(&mut response).await, 205 | Err(err) => handler.on_error(err).await, 206 | } 207 | } 208 | 209 | async fn run_job(client: &Arc, job: &Arc>) 210 | where 211 | T: JobHandler, 212 | { 213 | let builder = ChainableRequestBuilder::from_base_url(job.base_url.clone()); 214 | let chain = job.handler.request(builder); 215 | Maera::send_request(client, chain, &Arc::clone(&job.handler)).await; 216 | // match decision { 217 | // Decision::Authorize => { 218 | // Maera::authorize(&client, &job).await.unwrap(); 219 | // Maera::run_job(client, job).await; 220 | // } 221 | // Decision::Stop => { 222 | // todo!("Stopping is not implemented yet") 223 | // } 224 | // Decision::Continue => {} 225 | // } 226 | } 227 | 228 | pub async fn start(self) -> Result<(), tokio::task::JoinError> { 229 | let Maera { jobs, client } = self; 230 | 231 | for job in jobs.into_iter() { 232 | let job = Arc::new(job); 233 | 234 | tokio::spawn({ 235 | let job = Arc::clone(&job); 236 | let client = Arc::clone(&client); 237 | async move { 238 | Maera::authorize(&client, &job).await.unwrap(); 239 | // if let Some(authorize) = &job.authorizer { 240 | // authorize(); 241 | // } 242 | loop { 243 | Maera::run_job(&client, &job).await; 244 | } 245 | } 246 | }); 247 | } 248 | Ok(()) 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /maera-test/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "android_system_properties" 7 | version = "0.1.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 10 | dependencies = [ 11 | "libc", 12 | ] 13 | 14 | [[package]] 15 | name = "async-channel" 16 | version = "1.8.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" 19 | dependencies = [ 20 | "concurrent-queue", 21 | "event-listener", 22 | "futures-core", 23 | ] 24 | 25 | [[package]] 26 | name = "async-trait" 27 | version = "0.1.67" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "86ea188f25f0255d8f92797797c97ebf5631fa88178beb1a46fdf5622c9a00e4" 30 | dependencies = [ 31 | "proc-macro2", 32 | "quote", 33 | "syn 2.0.8", 34 | ] 35 | 36 | [[package]] 37 | name = "autocfg" 38 | version = "1.1.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 41 | 42 | [[package]] 43 | name = "bitflags" 44 | version = "1.3.2" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 47 | 48 | [[package]] 49 | name = "bumpalo" 50 | version = "3.12.0" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" 53 | 54 | [[package]] 55 | name = "bytes" 56 | version = "1.4.0" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 59 | 60 | [[package]] 61 | name = "castaway" 62 | version = "0.2.2" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" 65 | dependencies = [ 66 | "rustversion", 67 | ] 68 | 69 | [[package]] 70 | name = "cc" 71 | version = "1.0.79" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 74 | 75 | [[package]] 76 | name = "cfg-if" 77 | version = "1.0.0" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 80 | 81 | [[package]] 82 | name = "chrono" 83 | version = "0.4.24" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" 86 | dependencies = [ 87 | "iana-time-zone", 88 | "num-integer", 89 | "num-traits", 90 | "winapi", 91 | ] 92 | 93 | [[package]] 94 | name = "clokwerk" 95 | version = "0.4.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "bd108d365fcb6d7eddf17a6718eb6a33db18ba4178f8cc6b667f480710f10d76" 98 | dependencies = [ 99 | "chrono", 100 | ] 101 | 102 | [[package]] 103 | name = "codespan-reporting" 104 | version = "0.11.1" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 107 | dependencies = [ 108 | "termcolor", 109 | "unicode-width", 110 | ] 111 | 112 | [[package]] 113 | name = "concurrent-queue" 114 | version = "2.1.0" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" 117 | dependencies = [ 118 | "crossbeam-utils", 119 | ] 120 | 121 | [[package]] 122 | name = "core-foundation-sys" 123 | version = "0.8.3" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 126 | 127 | [[package]] 128 | name = "crossbeam-utils" 129 | version = "0.8.15" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" 132 | dependencies = [ 133 | "cfg-if", 134 | ] 135 | 136 | [[package]] 137 | name = "cxx" 138 | version = "1.0.93" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038" 141 | dependencies = [ 142 | "cc", 143 | "cxxbridge-flags", 144 | "cxxbridge-macro", 145 | "link-cplusplus", 146 | ] 147 | 148 | [[package]] 149 | name = "cxx-build" 150 | version = "1.0.93" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca" 153 | dependencies = [ 154 | "cc", 155 | "codespan-reporting", 156 | "once_cell", 157 | "proc-macro2", 158 | "quote", 159 | "scratch", 160 | "syn 2.0.8", 161 | ] 162 | 163 | [[package]] 164 | name = "cxxbridge-flags" 165 | version = "1.0.93" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31" 168 | 169 | [[package]] 170 | name = "cxxbridge-macro" 171 | version = "1.0.93" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" 174 | dependencies = [ 175 | "proc-macro2", 176 | "quote", 177 | "syn 2.0.8", 178 | ] 179 | 180 | [[package]] 181 | name = "encoding_rs" 182 | version = "0.8.32" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" 185 | dependencies = [ 186 | "cfg-if", 187 | ] 188 | 189 | [[package]] 190 | name = "event-listener" 191 | version = "2.5.3" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 194 | 195 | [[package]] 196 | name = "fnv" 197 | version = "1.0.7" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 200 | 201 | [[package]] 202 | name = "form_urlencoded" 203 | version = "1.1.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 206 | dependencies = [ 207 | "percent-encoding", 208 | ] 209 | 210 | [[package]] 211 | name = "futures" 212 | version = "0.3.27" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" 215 | dependencies = [ 216 | "futures-channel", 217 | "futures-core", 218 | "futures-executor", 219 | "futures-io", 220 | "futures-sink", 221 | "futures-task", 222 | "futures-util", 223 | ] 224 | 225 | [[package]] 226 | name = "futures-channel" 227 | version = "0.3.27" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" 230 | dependencies = [ 231 | "futures-core", 232 | "futures-sink", 233 | ] 234 | 235 | [[package]] 236 | name = "futures-core" 237 | version = "0.3.27" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" 240 | 241 | [[package]] 242 | name = "futures-executor" 243 | version = "0.3.27" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83" 246 | dependencies = [ 247 | "futures-core", 248 | "futures-task", 249 | "futures-util", 250 | ] 251 | 252 | [[package]] 253 | name = "futures-io" 254 | version = "0.3.27" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" 257 | 258 | [[package]] 259 | name = "futures-lite" 260 | version = "1.12.0" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" 263 | dependencies = [ 264 | "futures-core", 265 | "pin-project-lite", 266 | ] 267 | 268 | [[package]] 269 | name = "futures-macro" 270 | version = "0.3.27" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" 273 | dependencies = [ 274 | "proc-macro2", 275 | "quote", 276 | "syn 1.0.109", 277 | ] 278 | 279 | [[package]] 280 | name = "futures-sink" 281 | version = "0.3.27" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" 284 | 285 | [[package]] 286 | name = "futures-task" 287 | version = "0.3.27" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" 290 | 291 | [[package]] 292 | name = "futures-util" 293 | version = "0.3.27" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" 296 | dependencies = [ 297 | "futures-channel", 298 | "futures-core", 299 | "futures-io", 300 | "futures-macro", 301 | "futures-sink", 302 | "futures-task", 303 | "memchr", 304 | "pin-project-lite", 305 | "pin-utils", 306 | "slab", 307 | ] 308 | 309 | [[package]] 310 | name = "hermit-abi" 311 | version = "0.2.6" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 314 | dependencies = [ 315 | "libc", 316 | ] 317 | 318 | [[package]] 319 | name = "http" 320 | version = "0.2.9" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 323 | dependencies = [ 324 | "bytes", 325 | "fnv", 326 | "itoa", 327 | ] 328 | 329 | [[package]] 330 | name = "httpdate" 331 | version = "1.0.2" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 334 | 335 | [[package]] 336 | name = "iana-time-zone" 337 | version = "0.1.54" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" 340 | dependencies = [ 341 | "android_system_properties", 342 | "core-foundation-sys", 343 | "iana-time-zone-haiku", 344 | "js-sys", 345 | "wasm-bindgen", 346 | "windows", 347 | ] 348 | 349 | [[package]] 350 | name = "iana-time-zone-haiku" 351 | version = "0.1.1" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" 354 | dependencies = [ 355 | "cxx", 356 | "cxx-build", 357 | ] 358 | 359 | [[package]] 360 | name = "idna" 361 | version = "0.3.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 364 | dependencies = [ 365 | "unicode-bidi", 366 | "unicode-normalization", 367 | ] 368 | 369 | [[package]] 370 | name = "itoa" 371 | version = "1.0.6" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 374 | 375 | [[package]] 376 | name = "js-sys" 377 | version = "0.3.61" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" 380 | dependencies = [ 381 | "wasm-bindgen", 382 | ] 383 | 384 | [[package]] 385 | name = "libc" 386 | version = "0.2.140" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" 389 | 390 | [[package]] 391 | name = "libz-sys" 392 | version = "1.1.8" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" 395 | dependencies = [ 396 | "cc", 397 | "libc", 398 | "pkg-config", 399 | "vcpkg", 400 | ] 401 | 402 | [[package]] 403 | name = "link-cplusplus" 404 | version = "1.0.8" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 407 | dependencies = [ 408 | "cc", 409 | ] 410 | 411 | [[package]] 412 | name = "lock_api" 413 | version = "0.4.9" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 416 | dependencies = [ 417 | "autocfg", 418 | "scopeguard", 419 | ] 420 | 421 | [[package]] 422 | name = "log" 423 | version = "0.4.17" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 426 | dependencies = [ 427 | "cfg-if", 428 | ] 429 | 430 | [[package]] 431 | name = "maera" 432 | version = "0.1.1" 433 | dependencies = [ 434 | "async-trait", 435 | "clokwerk", 436 | "futures", 437 | "futures-io", 438 | "ratmom", 439 | "serde", 440 | "tokio", 441 | "url", 442 | ] 443 | 444 | [[package]] 445 | name = "maera-test" 446 | version = "0.1.0" 447 | dependencies = [ 448 | "async-trait", 449 | "maera", 450 | "serde", 451 | "serde_json", 452 | "tokio", 453 | ] 454 | 455 | [[package]] 456 | name = "memchr" 457 | version = "2.5.0" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 460 | 461 | [[package]] 462 | name = "mime" 463 | version = "0.3.17" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 466 | 467 | [[package]] 468 | name = "mio" 469 | version = "0.8.6" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" 472 | dependencies = [ 473 | "libc", 474 | "log", 475 | "wasi", 476 | "windows-sys 0.45.0", 477 | ] 478 | 479 | [[package]] 480 | name = "num-integer" 481 | version = "0.1.45" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 484 | dependencies = [ 485 | "autocfg", 486 | "num-traits", 487 | ] 488 | 489 | [[package]] 490 | name = "num-traits" 491 | version = "0.2.15" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 494 | dependencies = [ 495 | "autocfg", 496 | ] 497 | 498 | [[package]] 499 | name = "num_cpus" 500 | version = "1.15.0" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 503 | dependencies = [ 504 | "hermit-abi", 505 | "libc", 506 | ] 507 | 508 | [[package]] 509 | name = "once_cell" 510 | version = "1.17.1" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" 513 | 514 | [[package]] 515 | name = "parking_lot" 516 | version = "0.12.1" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 519 | dependencies = [ 520 | "lock_api", 521 | "parking_lot_core", 522 | ] 523 | 524 | [[package]] 525 | name = "parking_lot_core" 526 | version = "0.9.7" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" 529 | dependencies = [ 530 | "cfg-if", 531 | "libc", 532 | "redox_syscall", 533 | "smallvec", 534 | "windows-sys 0.45.0", 535 | ] 536 | 537 | [[package]] 538 | name = "percent-encoding" 539 | version = "2.2.0" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 542 | 543 | [[package]] 544 | name = "pin-project" 545 | version = "1.0.12" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" 548 | dependencies = [ 549 | "pin-project-internal", 550 | ] 551 | 552 | [[package]] 553 | name = "pin-project-internal" 554 | version = "1.0.12" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" 557 | dependencies = [ 558 | "proc-macro2", 559 | "quote", 560 | "syn 1.0.109", 561 | ] 562 | 563 | [[package]] 564 | name = "pin-project-lite" 565 | version = "0.2.9" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 568 | 569 | [[package]] 570 | name = "pin-utils" 571 | version = "0.1.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 574 | 575 | [[package]] 576 | name = "pkg-config" 577 | version = "0.3.26" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" 580 | 581 | [[package]] 582 | name = "polling" 583 | version = "2.6.0" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa" 586 | dependencies = [ 587 | "autocfg", 588 | "bitflags", 589 | "cfg-if", 590 | "concurrent-queue", 591 | "libc", 592 | "log", 593 | "pin-project-lite", 594 | "windows-sys 0.45.0", 595 | ] 596 | 597 | [[package]] 598 | name = "proc-macro2" 599 | version = "1.0.53" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" 602 | dependencies = [ 603 | "unicode-ident", 604 | ] 605 | 606 | [[package]] 607 | name = "quote" 608 | version = "1.0.26" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" 611 | dependencies = [ 612 | "proc-macro2", 613 | ] 614 | 615 | [[package]] 616 | name = "ratcurl" 617 | version = "0.1.0" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "b83eb90b2b1ec439212b89b6e79f283bdd94378c5e418e1b2799b85f207dca51" 620 | dependencies = [ 621 | "libc", 622 | "ratcurl-sys", 623 | "schannel", 624 | "socket2", 625 | "winapi", 626 | ] 627 | 628 | [[package]] 629 | name = "ratcurl-sys" 630 | version = "0.1.0+curl-7.86.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "79717113223ca668b5054a7589e8f4424930a20096c69abb91ccd548e9461f73" 633 | dependencies = [ 634 | "cc", 635 | "libc", 636 | "libz-sys", 637 | "pkg-config", 638 | "vcpkg", 639 | "winapi", 640 | ] 641 | 642 | [[package]] 643 | name = "ratmom" 644 | version = "0.1.0" 645 | source = "git+https://codeberg.org/transcast/ratmom.git#9942c0670ccb47f137d2b54bece8154ae863676e" 646 | dependencies = [ 647 | "async-channel", 648 | "castaway", 649 | "crossbeam-utils", 650 | "encoding_rs", 651 | "event-listener", 652 | "futures-io", 653 | "futures-lite", 654 | "http", 655 | "httpdate", 656 | "log", 657 | "mime", 658 | "once_cell", 659 | "polling", 660 | "ratcurl", 661 | "ratcurl-sys", 662 | "sluice", 663 | "tracing", 664 | "tracing-futures", 665 | "url", 666 | "waker-fn", 667 | ] 668 | 669 | [[package]] 670 | name = "redox_syscall" 671 | version = "0.2.16" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 674 | dependencies = [ 675 | "bitflags", 676 | ] 677 | 678 | [[package]] 679 | name = "rustversion" 680 | version = "1.0.12" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" 683 | 684 | [[package]] 685 | name = "ryu" 686 | version = "1.0.13" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 689 | 690 | [[package]] 691 | name = "schannel" 692 | version = "0.1.21" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" 695 | dependencies = [ 696 | "windows-sys 0.42.0", 697 | ] 698 | 699 | [[package]] 700 | name = "scopeguard" 701 | version = "1.1.0" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 704 | 705 | [[package]] 706 | name = "scratch" 707 | version = "1.0.5" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" 710 | 711 | [[package]] 712 | name = "serde" 713 | version = "1.0.158" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" 716 | dependencies = [ 717 | "serde_derive", 718 | ] 719 | 720 | [[package]] 721 | name = "serde_derive" 722 | version = "1.0.158" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" 725 | dependencies = [ 726 | "proc-macro2", 727 | "quote", 728 | "syn 2.0.8", 729 | ] 730 | 731 | [[package]] 732 | name = "serde_json" 733 | version = "1.0.94" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" 736 | dependencies = [ 737 | "itoa", 738 | "ryu", 739 | "serde", 740 | ] 741 | 742 | [[package]] 743 | name = "signal-hook-registry" 744 | version = "1.4.1" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 747 | dependencies = [ 748 | "libc", 749 | ] 750 | 751 | [[package]] 752 | name = "slab" 753 | version = "0.4.8" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 756 | dependencies = [ 757 | "autocfg", 758 | ] 759 | 760 | [[package]] 761 | name = "sluice" 762 | version = "0.5.5" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" 765 | dependencies = [ 766 | "async-channel", 767 | "futures-core", 768 | "futures-io", 769 | ] 770 | 771 | [[package]] 772 | name = "smallvec" 773 | version = "1.10.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 776 | 777 | [[package]] 778 | name = "socket2" 779 | version = "0.4.9" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 782 | dependencies = [ 783 | "libc", 784 | "winapi", 785 | ] 786 | 787 | [[package]] 788 | name = "syn" 789 | version = "1.0.109" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 792 | dependencies = [ 793 | "proc-macro2", 794 | "quote", 795 | "unicode-ident", 796 | ] 797 | 798 | [[package]] 799 | name = "syn" 800 | version = "2.0.8" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9" 803 | dependencies = [ 804 | "proc-macro2", 805 | "quote", 806 | "unicode-ident", 807 | ] 808 | 809 | [[package]] 810 | name = "termcolor" 811 | version = "1.2.0" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" 814 | dependencies = [ 815 | "winapi-util", 816 | ] 817 | 818 | [[package]] 819 | name = "tinyvec" 820 | version = "1.6.0" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 823 | dependencies = [ 824 | "tinyvec_macros", 825 | ] 826 | 827 | [[package]] 828 | name = "tinyvec_macros" 829 | version = "0.1.1" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 832 | 833 | [[package]] 834 | name = "tokio" 835 | version = "1.26.0" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" 838 | dependencies = [ 839 | "autocfg", 840 | "bytes", 841 | "libc", 842 | "memchr", 843 | "mio", 844 | "num_cpus", 845 | "parking_lot", 846 | "pin-project-lite", 847 | "signal-hook-registry", 848 | "socket2", 849 | "tokio-macros", 850 | "windows-sys 0.45.0", 851 | ] 852 | 853 | [[package]] 854 | name = "tokio-macros" 855 | version = "1.8.2" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" 858 | dependencies = [ 859 | "proc-macro2", 860 | "quote", 861 | "syn 1.0.109", 862 | ] 863 | 864 | [[package]] 865 | name = "tracing" 866 | version = "0.1.37" 867 | source = "registry+https://github.com/rust-lang/crates.io-index" 868 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 869 | dependencies = [ 870 | "cfg-if", 871 | "log", 872 | "pin-project-lite", 873 | "tracing-attributes", 874 | "tracing-core", 875 | ] 876 | 877 | [[package]] 878 | name = "tracing-attributes" 879 | version = "0.1.23" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" 882 | dependencies = [ 883 | "proc-macro2", 884 | "quote", 885 | "syn 1.0.109", 886 | ] 887 | 888 | [[package]] 889 | name = "tracing-core" 890 | version = "0.1.30" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 893 | dependencies = [ 894 | "once_cell", 895 | ] 896 | 897 | [[package]] 898 | name = "tracing-futures" 899 | version = "0.2.5" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" 902 | dependencies = [ 903 | "pin-project", 904 | "tracing", 905 | ] 906 | 907 | [[package]] 908 | name = "unicode-bidi" 909 | version = "0.3.13" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 912 | 913 | [[package]] 914 | name = "unicode-ident" 915 | version = "1.0.8" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 918 | 919 | [[package]] 920 | name = "unicode-normalization" 921 | version = "0.1.22" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 924 | dependencies = [ 925 | "tinyvec", 926 | ] 927 | 928 | [[package]] 929 | name = "unicode-width" 930 | version = "0.1.10" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 933 | 934 | [[package]] 935 | name = "url" 936 | version = "2.3.1" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 939 | dependencies = [ 940 | "form_urlencoded", 941 | "idna", 942 | "percent-encoding", 943 | ] 944 | 945 | [[package]] 946 | name = "vcpkg" 947 | version = "0.2.15" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 950 | 951 | [[package]] 952 | name = "waker-fn" 953 | version = "1.1.0" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" 956 | 957 | [[package]] 958 | name = "wasi" 959 | version = "0.11.0+wasi-snapshot-preview1" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 962 | 963 | [[package]] 964 | name = "wasm-bindgen" 965 | version = "0.2.84" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" 968 | dependencies = [ 969 | "cfg-if", 970 | "wasm-bindgen-macro", 971 | ] 972 | 973 | [[package]] 974 | name = "wasm-bindgen-backend" 975 | version = "0.2.84" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" 978 | dependencies = [ 979 | "bumpalo", 980 | "log", 981 | "once_cell", 982 | "proc-macro2", 983 | "quote", 984 | "syn 1.0.109", 985 | "wasm-bindgen-shared", 986 | ] 987 | 988 | [[package]] 989 | name = "wasm-bindgen-macro" 990 | version = "0.2.84" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" 993 | dependencies = [ 994 | "quote", 995 | "wasm-bindgen-macro-support", 996 | ] 997 | 998 | [[package]] 999 | name = "wasm-bindgen-macro-support" 1000 | version = "0.2.84" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" 1003 | dependencies = [ 1004 | "proc-macro2", 1005 | "quote", 1006 | "syn 1.0.109", 1007 | "wasm-bindgen-backend", 1008 | "wasm-bindgen-shared", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "wasm-bindgen-shared" 1013 | version = "0.2.84" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" 1016 | 1017 | [[package]] 1018 | name = "winapi" 1019 | version = "0.3.9" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1022 | dependencies = [ 1023 | "winapi-i686-pc-windows-gnu", 1024 | "winapi-x86_64-pc-windows-gnu", 1025 | ] 1026 | 1027 | [[package]] 1028 | name = "winapi-i686-pc-windows-gnu" 1029 | version = "0.4.0" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1032 | 1033 | [[package]] 1034 | name = "winapi-util" 1035 | version = "0.1.5" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1038 | dependencies = [ 1039 | "winapi", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "winapi-x86_64-pc-windows-gnu" 1044 | version = "0.4.0" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1047 | 1048 | [[package]] 1049 | name = "windows" 1050 | version = "0.46.0" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" 1053 | dependencies = [ 1054 | "windows-targets", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "windows-sys" 1059 | version = "0.42.0" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 1062 | dependencies = [ 1063 | "windows_aarch64_gnullvm", 1064 | "windows_aarch64_msvc", 1065 | "windows_i686_gnu", 1066 | "windows_i686_msvc", 1067 | "windows_x86_64_gnu", 1068 | "windows_x86_64_gnullvm", 1069 | "windows_x86_64_msvc", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "windows-sys" 1074 | version = "0.45.0" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 1077 | dependencies = [ 1078 | "windows-targets", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "windows-targets" 1083 | version = "0.42.2" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 1086 | dependencies = [ 1087 | "windows_aarch64_gnullvm", 1088 | "windows_aarch64_msvc", 1089 | "windows_i686_gnu", 1090 | "windows_i686_msvc", 1091 | "windows_x86_64_gnu", 1092 | "windows_x86_64_gnullvm", 1093 | "windows_x86_64_msvc", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "windows_aarch64_gnullvm" 1098 | version = "0.42.2" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 1101 | 1102 | [[package]] 1103 | name = "windows_aarch64_msvc" 1104 | version = "0.42.2" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 1107 | 1108 | [[package]] 1109 | name = "windows_i686_gnu" 1110 | version = "0.42.2" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 1113 | 1114 | [[package]] 1115 | name = "windows_i686_msvc" 1116 | version = "0.42.2" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 1119 | 1120 | [[package]] 1121 | name = "windows_x86_64_gnu" 1122 | version = "0.42.2" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 1125 | 1126 | [[package]] 1127 | name = "windows_x86_64_gnullvm" 1128 | version = "0.42.2" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 1131 | 1132 | [[package]] 1133 | name = "windows_x86_64_msvc" 1134 | version = "0.42.2" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 1137 | --------------------------------------------------------------------------------