57cda1281b
Move entire Go tree to archive/go/ preserving history. Add Rust implementation: axum HTTP server, nostr-sdk relay reader, sqlx/SQLite storage, Torznab caps+search endpoints, figment config, clap CLI. Update spec.md tech stack and repo layout to reflect Rust. Add docs/FIPS.md with Mode A/B/C deployment walkthrough. Add Phase 6 (FIPS deployment) to phase plan.
169 lines
4.2 KiB
Rust
169 lines
4.2 KiB
Rust
use serde::Serialize;
|
|
|
|
// ─── Caps ─────────────────────────────────────────────────────────────────────
|
|
|
|
#[derive(Serialize)]
|
|
#[serde(rename = "caps")]
|
|
pub struct Caps {
|
|
pub server: CapsServer,
|
|
pub limits: CapsLimits,
|
|
pub searching: CapsSearching,
|
|
pub categories: CapsCategories,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsServer {
|
|
#[serde(rename = "@version")]
|
|
pub version: String,
|
|
#[serde(rename = "@title")]
|
|
pub title: String,
|
|
#[serde(rename = "@strapline")]
|
|
pub strapline: String,
|
|
#[serde(rename = "@email")]
|
|
pub email: String,
|
|
#[serde(rename = "@url")]
|
|
pub url: String,
|
|
#[serde(rename = "@image")]
|
|
pub image: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsLimits {
|
|
#[serde(rename = "@max")]
|
|
pub max: u32,
|
|
#[serde(rename = "@default")]
|
|
pub default: u32,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsSearching {
|
|
pub search: CapsSearch,
|
|
#[serde(rename = "tv-search")]
|
|
pub tv_search: CapsSearch,
|
|
#[serde(rename = "movie-search")]
|
|
pub movie_search: CapsSearch,
|
|
#[serde(rename = "music-search")]
|
|
pub music_search: CapsSearch,
|
|
#[serde(rename = "audio-search")]
|
|
pub audio_search: CapsSearch,
|
|
#[serde(rename = "book-search")]
|
|
pub book_search: CapsSearch,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsSearch {
|
|
#[serde(rename = "@available")]
|
|
pub available: String,
|
|
#[serde(rename = "@supportedParams")]
|
|
pub supported_params: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsCategories {
|
|
#[serde(rename = "category")]
|
|
pub categories: Vec<CapsCategory>,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsCategory {
|
|
#[serde(rename = "@id")]
|
|
pub id: u32,
|
|
#[serde(rename = "@name")]
|
|
pub name: String,
|
|
#[serde(rename = "subcat")]
|
|
pub subcats: Vec<CapsSubcat>,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct CapsSubcat {
|
|
#[serde(rename = "@id")]
|
|
pub id: u32,
|
|
#[serde(rename = "@name")]
|
|
pub name: String,
|
|
}
|
|
|
|
// ─── RSS (search results) ─────────────────────────────────────────────────────
|
|
|
|
#[derive(Serialize)]
|
|
#[serde(rename = "rss")]
|
|
pub struct Rss {
|
|
#[serde(rename = "@version")]
|
|
pub version: String,
|
|
#[serde(rename = "@xmlns:atom")]
|
|
pub xmlns_atom: String,
|
|
#[serde(rename = "@xmlns:torznab")]
|
|
pub xmlns_torznab: String,
|
|
pub channel: RssChannel,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct RssChannel {
|
|
#[serde(rename = "atom:link")]
|
|
pub atom_link: AtomLink,
|
|
pub title: String,
|
|
pub description: String,
|
|
pub link: String,
|
|
pub language: String,
|
|
pub category: String,
|
|
#[serde(rename = "item")]
|
|
pub items: Vec<RssItem>,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct AtomLink {
|
|
#[serde(rename = "@rel")]
|
|
pub rel: String,
|
|
#[serde(rename = "@type")]
|
|
pub type_: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct RssItem {
|
|
pub title: String,
|
|
pub guid: RssGuid,
|
|
pub link: String,
|
|
#[serde(rename = "pubDate")]
|
|
pub pub_date: String,
|
|
pub size: i64,
|
|
pub enclosure: RssEnclosure,
|
|
#[serde(rename = "torznab:attr")]
|
|
pub attrs: Vec<TorznabAttr>,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct RssGuid {
|
|
#[serde(rename = "@isPermaLink")]
|
|
pub is_perma_link: String,
|
|
#[serde(rename = "$text")]
|
|
pub value: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct RssEnclosure {
|
|
#[serde(rename = "@url")]
|
|
pub url: String,
|
|
#[serde(rename = "@length")]
|
|
pub length: i64,
|
|
#[serde(rename = "@type")]
|
|
pub type_: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct TorznabAttr {
|
|
#[serde(rename = "@name")]
|
|
pub name: String,
|
|
#[serde(rename = "@value")]
|
|
pub value: String,
|
|
}
|
|
|
|
// ─── Error ────────────────────────────────────────────────────────────────────
|
|
|
|
#[derive(Serialize)]
|
|
#[serde(rename = "error")]
|
|
pub struct ErrorResponse {
|
|
#[serde(rename = "@code")]
|
|
pub code: u32,
|
|
#[serde(rename = "@description")]
|
|
pub description: String,
|
|
}
|