1use serde::{Deserialize, Serialize, Serializer};
4use std::borrow::Cow;
5use thiserror::Error;
6use warg_crypto::hash::HashAlgorithm;
7use warg_protocol::registry::RegistryIndex;
8
9#[derive(Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct LedgerSourcesResponse {
13 pub hash_algorithm: HashAlgorithm,
15 pub sources: Vec<LedgerSource>,
17}
18
19#[derive(Serialize, Deserialize)]
21#[serde(rename_all = "camelCase")]
22pub struct LedgerSource {
23 pub first_registry_index: RegistryIndex,
25 pub last_registry_index: RegistryIndex,
27 pub url: String,
29 pub content_type: LedgerSourceContentType,
31 #[serde(default, skip_serializing_if = "is_false")]
33 pub accept_ranges: bool,
34}
35
36fn is_false(b: &bool) -> bool {
37 !b
38}
39
40#[derive(Default, PartialEq, Serialize, Deserialize, Debug)]
42pub enum LedgerSourceContentType {
43 #[default]
47 #[serde(rename = "application/vnd.warg.ledger.packed")]
48 Packed,
49}
50
51impl LedgerSourceContentType {
52 pub fn as_str(&self) -> &'static str {
54 match self {
55 Self::Packed => "application/vnd.warg.ledger.packed",
56 }
57 }
58}
59
60#[non_exhaustive]
62#[derive(Debug, Error)]
63pub enum LedgerError {
64 #[error("{message}")]
66 Message {
67 status: u16,
69 message: String,
71 },
72}
73
74impl LedgerError {
75 pub fn status(&self) -> u16 {
77 match self {
78 Self::Message { status, .. } => *status,
79 }
80 }
81}
82
83#[derive(Serialize, Deserialize)]
84#[serde(untagged, rename_all = "camelCase")]
85enum RawError<'a> {
86 Message { status: u16, message: Cow<'a, str> },
87}
88
89impl Serialize for LedgerError {
90 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
91 match self {
92 Self::Message { status, message } => RawError::Message {
93 status: *status,
94 message: Cow::Borrowed(message),
95 }
96 .serialize(serializer),
97 }
98 }
99}
100
101impl<'de> Deserialize<'de> for LedgerError {
102 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
103 where
104 D: serde::Deserializer<'de>,
105 {
106 match RawError::deserialize(deserializer)? {
107 RawError::Message { status, message } => Ok(Self::Message {
108 status,
109 message: message.into_owned(),
110 }),
111 }
112 }
113}