use crate::primaries::Primary;
use waddling_errors::ComponentIdDocumented;
use waddling_errors::prelude::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Api;
impl ComponentId for Api {
fn as_str(&self) -> &'static str {
"Api"
}
}
impl ComponentIdDocumented for Api {
fn description(&self) -> Option<&'static str> {
Some(
"External API integrations. Manages third-party service calls, webhook handling, \
and API rate limiting.",
)
}
fn examples(&self) -> &'static [&'static str] {
&[
"B.Api.RateLimit.007: Rate limit exceeded (100 req/min)",
"E.Api.Connection.028: Third-party API unreachable",
"W.Api.Validation.003: Response schema validation warning",
]
}
fn tags(&self) -> &'static [&'static str] {
&["integration", "http", "webhooks"]
}
}
pub const BLOCKED_RATELIMIT: Code<Api, Primary> = Code::blocked(Api, Primary::RateLimit, 7);
pub const ERR_CONNECTION_UNREACHABLE: Code<Api, Primary> =
Code::error(Api, Primary::Connection, 28);
pub const ERR_CONNECTION_UNAVAILABLE: Code<Api, Primary> =
Code::error(Api, Primary::Connection, 27);
pub const WARN_VALIDATION_INVALID: Code<Api, Primary> = Code::warning(Api, Primary::Validation, 3);
pub const ERR_TIMEOUT: Code<Api, Primary> = Code::error(Api, Primary::Timeout, 17);
#[cfg(feature = "doc-gen")]
pub fn register_component(generator: &mut waddling_errors::doc_generator::DocRegistry) {
use waddling_errors::Role;
generator.register_component(
"Api",
Some("External API integrations. Manages third-party service calls, webhook handling, and API rate limiting. Implements circuit breaker pattern, retry logic with exponential backoff, and request/response logging."),
&[
"RESTful API client with retries",
"Webhook signature verification",
"Rate limit tracking (token bucket)",
"Circuit breaker for fault tolerance",
"Request timeout and cancellation",
"Response caching and validation",
],
&["Api", "integration", "http", "webhooks", "rest", "circuit-breaker"]);
generator.register_component_location_with_role(
"Api",
"examples/complete_system/components/api.rs",
Some(Role::Public),
);
generator.register_component_location_with_role(
"Api",
"examples/api_integration_guide.rs",
Some(Role::Public),
);
generator.register_component_location_with_role(
"Api",
"examples/webhook_examples.rs",
Some(Role::Public),
);
generator.register_component_location_with_role(
"Api",
"src/clients/mock_api.rs",
Some(Role::Developer),
);
generator.register_component_location_with_role(
"Api",
"src/middleware/request_logger.rs",
Some(Role::Developer),
);
generator.register_component_location_with_role(
"Api",
"src/clients/external_api.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Api",
"src/middleware/rate_limiter.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Api",
"src/handlers/webhook_handler.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Api",
"src/clients/circuit_breaker.rs",
Some(Role::Internal),
);
generator.register_component_location_with_role(
"Api",
"src/clients/api_secrets.rs",
Some(Role::Internal),
);
}
#[cfg(feature = "doc-gen")]
pub fn register_errors(generator: &mut waddling_errors::doc_generator::DocRegistry) {
use waddling_errors::Role;
let errors = vec![
(
"B.Api.RateLimit.007",
"API rate limit exceeded",
&[
"Implement backoff",
"Check X-RateLimit-Reset",
"Cache responses",
][..],
&["Api", "rate-limiting"][..],
Role::Public,
),
(
"E.Api.Connection.028",
"Third-party API unreachable",
&[
"Check network",
"Verify endpoint URL",
"Check service status",
],
&["Api", "network", "external"],
Role::Developer,
),
(
"E.Api.Connection.027",
"Third-party API temporarily unavailable",
&[
"Retry after delay",
"Enable circuit breaker",
"Use fallback",
],
&["Api", "resilience"],
Role::Developer,
),
(
"W.Api.Validation.003",
"API response validation warning",
&[
"Check API version",
"Review schema changes",
"Update client",
],
&["Api", "validation", "compatibility"],
Role::Developer,
),
(
"E.Api.Timeout.017",
"API request timeout",
&[
"Increase timeout",
"Optimize payload size",
"Use async endpoints",
],
&["Api", "performance"],
Role::Developer,
),
];
for (code, desc, hints, tags, role) in &errors {
let _ = generator.register(*code, *desc, hints, tags);
let snippet = match role {
Role::Internal => format!(
"// Internal debugging\nlog::error!(\"[{}] {}\");",
code, desc
),
Role::Developer => format!(
"// Developer API usage\nif let Err(e) = operation() {{\n eprintln!(\"Error: {}\");\n}}",
code
),
Role::Public => format!(
"// Public error handling\nmatch result {{\n Err(_) => println!(\"Operation failed: {}\"),\n Ok(_) => println!(\"Success\"),\n}}",
desc
),
};
generator.add_snippet_for_role(
format!("{:?} - Usage Example", role),
"rust",
snippet,
*role,
);
}
}
pub fn demo() {
println!("🌐 API Component Errors:\n");
println!(" {} - Rate limit exceeded", BLOCKED_RATELIMIT.code());
println!(" {} - API unreachable", ERR_CONNECTION_UNREACHABLE.code());
println!(" {} - API unavailable", ERR_CONNECTION_UNAVAILABLE.code());
println!(" {} - Validation warning", WARN_VALIDATION_INVALID.code());
println!(" {} - Request timeout", ERR_TIMEOUT.code());
}