diff --git a/Cargo.lock b/Cargo.lock index 52000af4c8..7d0282dc40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,7 +185,7 @@ dependencies = [ "futures-core", "futures-util", "mio 0.8.11", - "socket2", + "socket2 0.5.7", "tokio", "tracing", ] @@ -246,7 +246,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec 1.13.2", - "socket2", + "socket2 0.5.7", "time", "url", ] @@ -672,7 +672,7 @@ dependencies = [ "openai_sora_client", "primitives", "rand 0.9.1", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -939,6 +939,22 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "async-tungstenite" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef0f7efedeac57d9b26170f72965ecfd31473ca52ca7a64e925b0b6f5f079886" +dependencies = [ + "atomic-waker", + "futures-core", + "futures-io", + "futures-task", + "futures-util", + "log", + "pin-project-lite", + "tungstenite", +] + [[package]] name = "atk" version = "0.18.2" @@ -3574,7 +3590,7 @@ dependencies = [ "image", "log", "percent-encoding-rfc3986", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_json", "smart-default 0.7.1", @@ -3601,7 +3617,7 @@ dependencies = [ "file_to_base64_url", "futures 0.3.31", "log", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "test_data", "testing", @@ -4073,7 +4089,7 @@ version = "0.1.0" dependencies = [ "cargo-manifest", "percent-encoding", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_json", "tokio", @@ -4284,7 +4300,7 @@ dependencies = [ "coarsetime", "errors", "jwt-simple", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -4714,7 +4730,7 @@ dependencies = [ "httpdate", "itoa 1.0.11", "pin-project-lite", - "socket2", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -4803,21 +4819,28 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" dependencies = [ + "base64 0.22.1", "bytes 1.10.1", "futures-channel", + "futures-core", "futures-util", "http 1.1.0", "http-body 1.0.0", "hyper 1.6.0", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.0", + "system-configuration 0.6.1", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -5175,7 +5198,7 @@ dependencies = [ "rand 0.8.5", "redis_common", "redis_schema", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -5243,6 +5266,16 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.0" @@ -5567,7 +5600,7 @@ dependencies = [ "nom", "once_cell", "quoted_printable", - "socket2", + "socket2 0.5.7", "tokio", "url", ] @@ -5616,9 +5649,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.170" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libfuzzer-sys" @@ -6019,6 +6052,26 @@ dependencies = [ "workspace-build-acceleration", ] +[[package]] +name = "midjourney_client" +version = "0.0.1" +dependencies = [ + "anyhow", + "cloudflare_errors", + "errors", + "futures 0.3.31", + "log", + "reqwest 0.12.22", + "reqwest-websocket", + "serde", + "serde_json", + "test_data", + "testing", + "tokio", + "url", + "workspace-build-acceleration", +] + [[package]] name = "migration" version = "0.0.1" @@ -6856,7 +6909,7 @@ dependencies = [ "log", "once_cell", "rand 0.9.1", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -6884,7 +6937,7 @@ dependencies = [ "log", "once_cell", "rand 0.9.1", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -7836,7 +7889,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls 0.23.13", - "socket2", + "socket2 0.5.7", "thiserror 1.0.63", "tokio", "tracing", @@ -7867,7 +7920,7 @@ checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" dependencies = [ "libc", "once_cell", - "socket2", + "socket2 0.5.7", "tracing", "windows-sys 0.52.0", ] @@ -8357,9 +8410,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" dependencies = [ "async-compression", "base64 0.22.1", @@ -8378,39 +8431,52 @@ dependencies = [ "hyper-rustls", "hyper-tls 0.6.0", "hyper-util", - "ipnet", "js-sys", "log", "mime", "mime_guess", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls 0.23.13", "rustls-native-certs", - "rustls-pemfile 2.1.2", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration 0.6.1", "tokio", "tokio-native-tls", "tokio-rustls", - "tokio-socks", "tokio-util", "tower 0.5.2", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.2", - "windows-registry", + "webpki-roots 1.0.2", +] + +[[package]] +name = "reqwest-websocket" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f91a811daaa8b54faeaec9d507a336897a3d243834a4965254a17d39da8b5c9" +dependencies = [ + "async-tungstenite", + "bytes 1.10.1", + "futures-util", + "reqwest 0.12.22", + "thiserror 2.0.12", + "tokio", + "tokio-util", + "tracing", + "tungstenite", + "web-sys", ] [[package]] @@ -8558,7 +8624,7 @@ dependencies = [ "log", "once_cell", "rand 0.9.1", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -8638,7 +8704,7 @@ dependencies = [ "minidom", "percent-encoding", "quick-xml 0.36.2", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -8781,9 +8847,12 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" @@ -9406,7 +9475,7 @@ dependencies = [ "log", "openai_sora_client", "r2d2_redis", - "reqwest 0.12.15", + "reqwest 0.12.22", "workspace-build-acceleration", ] @@ -9533,6 +9602,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "softbuffer" version = "0.4.6" @@ -9960,7 +10039,7 @@ dependencies = [ "redis_common", "redis_schema", "regex", - "reqwest 0.12.15", + "reqwest 0.12.22", "reusable_types", "rust-s3", "serde", @@ -10008,7 +10087,7 @@ dependencies = [ "idempotency", "log", "mimetypes", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -10511,7 +10590,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_json", "serde_repr", @@ -10663,7 +10742,7 @@ dependencies = [ "data-url", "http 1.1.0", "regex", - "reqwest 0.12.15", + "reqwest 0.12.22", "schemars", "serde", "serde_json", @@ -10708,7 +10787,7 @@ dependencies = [ "futures-util", "log", "read-progress-stream", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_json", "tauri", @@ -10932,7 +11011,7 @@ version = "0.1.0" dependencies = [ "easyenv", "log", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde_json", "workspace-build-acceleration", ] @@ -11056,7 +11135,7 @@ dependencies = [ "parking_lot 0.12.2", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.7", "tokio-macros", "tracing", "windows-sys 0.52.0", @@ -11155,18 +11234,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-socks" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" -dependencies = [ - "either", - "futures-util", - "thiserror 1.0.63", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.16" @@ -11228,6 +11295,7 @@ checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes 1.10.1", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -11384,6 +11452,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.5.0", + "bytes 1.10.1", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "iri-string", + "pin-project-lite", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -11542,7 +11628,7 @@ dependencies = [ "memory_caching", "mysql_queries", "r2d2_redis", - "reqwest 0.12.15", + "reqwest 0.12.22", "serde", "serde_derive", "serde_json", @@ -11570,6 +11656,23 @@ dependencies = [ "workspace-build-acceleration", ] +[[package]] +name = "tungstenite" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +dependencies = [ + "bytes 1.10.1", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand 0.9.1", + "sha1 0.10.6", + "thiserror 2.0.12", + "utf-8", +] + [[package]] name = "typeid" version = "1.0.2" @@ -11824,7 +11927,7 @@ dependencies = [ "actix-web", "mime_guess", "regex", - "reqwest 0.12.15", + "reqwest 0.12.22", "rust-embed", "serde", "serde_json", @@ -12239,7 +12342,7 @@ dependencies = [ "errors", "log", "once_cell", - "reqwest 0.12.15", + "reqwest 0.12.22", "rss", "scraper", "serde", @@ -12308,6 +12411,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.36.0" @@ -12478,7 +12590,7 @@ dependencies = [ "windows-interface", "windows-link", "windows-result", - "windows-strings", + "windows-strings 0.3.1", ] [[package]] @@ -12531,20 +12643,20 @@ dependencies = [ [[package]] name = "windows-registry" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820" dependencies = [ + "windows-link", "windows-result", - "windows-strings", - "windows-targets 0.53.0", + "windows-strings 0.4.2", ] [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] @@ -12558,6 +12670,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -12972,7 +13093,7 @@ dependencies = [ "regex", "regex-automata", "regex-syntax", - "reqwest 0.12.15", + "reqwest 0.12.22", "rsa", "rustls-pki-types", "schemars", @@ -12984,7 +13105,7 @@ dependencies = [ "sha1 0.10.6", "sha2 0.10.8", "smallvec 1.13.2", - "socket2", + "socket2 0.5.7", "spin 0.9.8", "sqlx", "sqlx-core", diff --git a/Cargo.toml b/Cargo.toml index a19f37f4e5..0fc541cb51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "crates/api_clients/fal_client", "crates/api_clients/google_drive_common", "crates/api_clients/google_sign_in", + "crates/api_clients/midjourney_client", "crates/api_clients/openai_sora_client", "crates/api_clients/openart_client", "crates/api_clients/runwayml_client", @@ -199,7 +200,8 @@ log = "0.4.27" once_cell = "1.21.3" rand = "0.9.1" regex = "1.11.1" -reqwest = { version = "0.12.15", features = ["json", "cookies"] } +reqwest = { version = "0.12.22", features = ["json", "cookies"] } +reqwest-websocket = { version = "0.5.0" } serde = { version = "1.0.219", features = ["derive"] } serde_derive = "1.0.219" serde_json = "1.0.140" @@ -230,6 +232,7 @@ images = { path = "crates/lib/files/images" } jwt_light = { path = "crates/lib/jwt_light" } memory_caching = { path = "crates/lib/caching/memory_caching" } memory_store = { path = "crates/lib/caching/memory_store" } +midjourney_client = { path = "crates/lib/files/midjourney_client" } mimetypes = { path = "crates/lib/files/mimetypes" } openai_sora_client = { path = "crates/api_clients/openai_sora_client" } primitives = { path = "crates/lib/data/primitives" } diff --git a/crates/api_clients/midjourney_client/Cargo.toml b/crates/api_clients/midjourney_client/Cargo.toml new file mode 100644 index 0000000000..33510ed051 --- /dev/null +++ b/crates/api_clients/midjourney_client/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "midjourney_client" +edition = "2024" +version = "0.0.1" +publish = false + +[package.metadata.cargo-udeps.ignore] +normal = ["workspace-build-acceleration"] + +[lib] +name = "midjourney_client" +path = "src/lib.rs" + +[dependencies] +# Workspace hack (faster compile times) +workspace-build-acceleration.workspace = true + +# Internal +cloudflare_errors.workspace = true +errors.workspace = true + +# External +anyhow.workspace = true +futures.workspace = true +log.workspace = true +reqwest-websocket.workspace = true +reqwest.workspace = true +serde.workspace = true +serde_json.workspace = true +tokio.workspace = true +url.workspace = true + +[dev-dependencies] +testing = { path = "../../lib/testing" } +test_data.workspace = true diff --git a/crates/api_clients/midjourney_client/src/error/midjourney_api_error.rs b/crates/api_clients/midjourney_client/src/error/midjourney_api_error.rs new file mode 100644 index 0000000000..7dfb69dffe --- /dev/null +++ b/crates/api_clients/midjourney_client/src/error/midjourney_api_error.rs @@ -0,0 +1,109 @@ +use cloudflare_errors::cloudflare_error::CloudflareError; +use errors::AnyhowError; +use std::error::Error; +use std::fmt::{Display, Formatter}; +use std::io; + +#[derive(Debug)] +pub enum MidjourneyApiError { + /// 400. The request was invalid. + InvalidRequest(String), + + /// 401. The request was not authorized. + Unauthorized(String), + + /// 403. The request was forbidden. + Forbidden(String), + + /// 404. The requested resource was not found. + NotFound(String), + + /// 429. Too many requests. + TooManyRequests(String), + + /// 500. An internal server error occurred. + InternalServerError { + body: String, + backend_hostname: Option, + }, + + /// Cloudflare errors. + CloudflareError(CloudflareError), + + /// A deserialization error with the response. + DeserializationError(serde_json::Error), + + /// The request timed out. + Timeout(String), + + /// A network error occurred. + NetworkError(String), + + /// Uncategorized reqwest error. + OtherReqwestError(reqwest::Error), + + /// An error doing file I/O (on our side) + IoError(io::Error), + + /// Another type of error. + Other(AnyhowError), +} + +impl Error for MidjourneyApiError {} + +impl Display for MidjourneyApiError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + // Server response code errors + Self::InvalidRequest(msg) => write!(f, "Invalid request: {}", msg), + Self::Unauthorized(msg) => write!(f, "Unauthorized: {}", msg), + Self::Forbidden(msg) => write!(f, "Forbidden: {}", msg), + Self::NotFound(msg) => write!(f, "Not found: {}", msg), + Self::TooManyRequests(msg) => write!(f, "Too many requests: {}", msg), + Self::InternalServerError {body, backend_hostname} => + write!(f, "Internal Server Error; backend hostname: {:?} ; body: {}; ", backend_hostname, body), + // Server response handling errors + Self::DeserializationError(error) => write!(f, "Deserialization error: {}", error), + // Network errors + Self::Timeout(msg) => write!(f, "Timeout: {}", msg), + Self::NetworkError(msg) => write!(f, "Network error: {}", msg), + // Cloudflare errors + Self::CloudflareError(error) => write!(f, "Cloudflare Error: {}", error), + // I/O errors + Self::IoError(error) => write!(f, "IO error: {}", error), + // Other + Self::OtherReqwestError(error) => write!(f, "Reqwest error: {}", error), + Self::Other(error) => write!(f, "Other error: {}", error), + } + } +} + +impl From for MidjourneyApiError { + fn from(error: reqwest::Error) -> Self { + if error.is_timeout() { + Self::Timeout(error.to_string()) + } else if error.is_connect() { + Self::NetworkError(error.to_string()) + } else { + Self::OtherReqwestError(error) + } + } +} + +impl From for MidjourneyApiError { + fn from(error: serde_json::Error) -> Self { + Self::DeserializationError(error) + } +} + +impl From for MidjourneyApiError { + fn from(error: io::Error) -> Self { + Self::IoError(error) + } +} + +impl From for MidjourneyApiError { + fn from(error: CloudflareError) -> Self { + Self::CloudflareError(error) + } +} diff --git a/crates/api_clients/midjourney_client/src/error/midjourney_client_error.rs b/crates/api_clients/midjourney_client/src/error/midjourney_client_error.rs new file mode 100644 index 0000000000..a354f63b0d --- /dev/null +++ b/crates/api_clients/midjourney_client/src/error/midjourney_client_error.rs @@ -0,0 +1,55 @@ +use std::error::Error; +use std::fmt::{Display, Formatter}; +use std::io; +use std::path::PathBuf; + +/// An error arising from the client, either before or after the request is sent. +#[derive(Debug)] +pub enum MidjourneyClientError { + /// Could not determine the filetype for the file. + FileTypeNotKnown(PathBuf), + + /// Could not handle the file type. + FileTypeNotHandled(PathBuf), + + /// An error doing file I/O (on our side) + IoError(io::Error), + + /// An error setting up the client + ReqwestError(reqwest::Error), + + /// A serialization error with the request. + SerializationError(serde_json::Error), +} + +impl Error for MidjourneyClientError {} + +impl Display for MidjourneyClientError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::FileTypeNotKnown(path) => write!(f, "Could not determine the filetype for the file: {:?}", path), + Self::FileTypeNotHandled(path) => write!(f, "Could not handle the file type for the file: {:?}", path), + Self::IoError(err) => write!(f, "IO error: {}", err), + Self::ReqwestError(err) => write!(f, "Reqwest client error: {}", err), + Self::SerializationError(err) => write!(f, "Request serialization error: {}", err), + } + } +} + +impl From for MidjourneyClientError { + fn from(error: io::Error) -> Self { + Self::IoError(error) + } +} + +impl From for MidjourneyClientError { + fn from(error: serde_json::Error) -> Self { + Self::SerializationError(error) + } +} + +impl From for MidjourneyClientError { + fn from(error: reqwest::Error) -> Self { + Self::ReqwestError(error) + } +} diff --git a/crates/api_clients/midjourney_client/src/error/midjourney_error.rs b/crates/api_clients/midjourney_client/src/error/midjourney_error.rs new file mode 100644 index 0000000000..61b6490ff7 --- /dev/null +++ b/crates/api_clients/midjourney_client/src/error/midjourney_error.rs @@ -0,0 +1,32 @@ +use crate::error::midjourney_api_error::MidjourneyApiError; +use crate::error::midjourney_client_error::MidjourneyClientError; +use std::error::Error; + +#[derive(Debug)] +pub enum MidjourneyError { + Api(MidjourneyApiError), + Client(MidjourneyClientError), +} + +impl Error for MidjourneyError {} + +impl std::fmt::Display for MidjourneyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Api(e) => write!(f, "Midjourney API error: {:?}", e), + Self::Client(e) => write!(f, "Midjourney Client error: {:?}", e), + } + } +} + +impl From for MidjourneyError { + fn from(error: MidjourneyApiError) -> Self { + Self::Api(error) + } +} + +impl From for MidjourneyError { + fn from(error: MidjourneyClientError) -> Self { + Self::Client(error) + } +} diff --git a/crates/api_clients/midjourney_client/src/error/mod.rs b/crates/api_clients/midjourney_client/src/error/mod.rs new file mode 100644 index 0000000000..ceefb7b1b1 --- /dev/null +++ b/crates/api_clients/midjourney_client/src/error/mod.rs @@ -0,0 +1,3 @@ +pub mod midjourney_error; +pub mod midjourney_api_error; +pub mod midjourney_client_error; \ No newline at end of file diff --git a/crates/api_clients/midjourney_client/src/lib.rs b/crates/api_clients/midjourney_client/src/lib.rs new file mode 100644 index 0000000000..0e7dfe54fb --- /dev/null +++ b/crates/api_clients/midjourney_client/src/lib.rs @@ -0,0 +1,3 @@ +//! A midjourney API client. + +pub mod error;