melodium_repository/
error.rs

1use crate::technical::{Availability, Element, Platform};
2use core::fmt::Display;
3use melodium_common::descriptor::{RepositoryError as CommonRepositoryError, Version};
4use std::path::PathBuf;
5
6#[derive(Debug)]
7pub enum RepositoryErrorKind {
8    AlreadyExistingPackage {
9        package: String,
10        version: Version,
11    },
12    UnknownPackage {
13        package: String,
14        version: Version,
15    },
16    FsError {
17        error: std::io::Error,
18    },
19    JsonError {
20        error: serde_json::Error,
21    },
22    NoNetwork,
23    NetworkError {
24        error: String,
25    },
26    PlatformDependant {
27        package: String,
28        version: Version,
29    },
30    NotPlatformDependant {
31        package: String,
32        version: Version,
33    },
34    PlatformUnavailable {
35        package: String,
36        version: Version,
37        platform: Platform,
38        availability: Availability,
39    },
40    PackageElementAbsent {
41        package: String,
42        version: Version,
43        platform: Option<(Platform, Availability)>,
44        element: Element,
45        path: PathBuf,
46    },
47}
48
49impl Display for RepositoryErrorKind {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        match self {
52            RepositoryErrorKind::AlreadyExistingPackage { package, version } => write!(
53                f,
54                "Package '{package}' version {version} already present in repository"
55            ),
56            RepositoryErrorKind::UnknownPackage { package, version } => write!(
57                f,
58                "Package '{package}' version {version} not found in repository"
59            ),
60            RepositoryErrorKind::FsError { error } => write!(f, "Filesystem error: {error}"),
61            RepositoryErrorKind::JsonError { error } => write!(f, "JSON error: {error}"),
62            RepositoryErrorKind::NoNetwork => write!(f, "No network ability for repository call"),
63            RepositoryErrorKind::NetworkError { error } => write!(f, "Network error: {error}"),
64            RepositoryErrorKind::PlatformDependant { package, version } => write!(f, "Package '{package}' version {version} is platform dependent"),
65            RepositoryErrorKind::NotPlatformDependant { package, version } => write!(f, "Package '{package}' version {version} is not platform dependent"),
66            RepositoryErrorKind::PlatformUnavailable { package, version, platform, availability } => write!(f, "Package '{package}' version {version} unavailable for '{platform}' as {availability}"),
67            RepositoryErrorKind::PackageElementAbsent { package, version, platform, element, path } => match platform {
68                Some((platform, availability)) => write!(f, "Element '{element}' of package '{package}' version {version} for '{platform}' ({availability}) is missing locally (looking at '{path}')", element = element.name, path = path.to_string_lossy()),
69                None => write!(f, "Element '{element}' of package '{package}' version {version} is missing locally (looking at '{path}')", element = element.name, path = path.to_string_lossy()),
70            },
71        }
72    }
73}
74
75#[derive(Debug)]
76pub struct RepositoryError {
77    pub id: u32,
78    pub kind: RepositoryErrorKind,
79}
80impl RepositoryError {
81    pub fn already_existing_package(id: u32, package: String, version: Version) -> Self {
82        Self {
83            id,
84            kind: RepositoryErrorKind::AlreadyExistingPackage { package, version },
85        }
86    }
87
88    pub fn unknown_package(id: u32, package: String, version: Version) -> Self {
89        Self {
90            id,
91            kind: RepositoryErrorKind::UnknownPackage { package, version },
92        }
93    }
94
95    pub fn fs_error(id: u32, error: std::io::Error) -> Self {
96        Self {
97            id,
98            kind: RepositoryErrorKind::FsError { error },
99        }
100    }
101
102    pub fn json_error(id: u32, error: serde_json::Error) -> Self {
103        Self {
104            id,
105            kind: RepositoryErrorKind::JsonError { error },
106        }
107    }
108
109    pub fn no_network(id: u32) -> Self {
110        Self {
111            id,
112            kind: RepositoryErrorKind::NoNetwork,
113        }
114    }
115
116    pub fn network_error(id: u32, error: String) -> Self {
117        Self {
118            id,
119            kind: RepositoryErrorKind::NetworkError { error },
120        }
121    }
122
123    pub fn platform_dependent(id: u32, package: String, version: Version) -> Self {
124        Self {
125            id,
126            kind: RepositoryErrorKind::PlatformDependant { package, version },
127        }
128    }
129
130    pub fn not_platform_dependent(id: u32, package: String, version: Version) -> Self {
131        Self {
132            id,
133            kind: RepositoryErrorKind::NotPlatformDependant { package, version },
134        }
135    }
136
137    pub fn platform_unavailable(
138        id: u32,
139        package: String,
140        version: Version,
141        platform: Platform,
142        availability: Availability,
143    ) -> Self {
144        Self {
145            id,
146            kind: RepositoryErrorKind::PlatformUnavailable {
147                package,
148                version,
149                platform,
150                availability,
151            },
152        }
153    }
154
155    pub fn package_element_absent(
156        id: u32,
157        package: String,
158        version: Version,
159        platform: Option<(Platform, Availability)>,
160        element: Element,
161        path: PathBuf,
162    ) -> Self {
163        Self {
164            id,
165            kind: RepositoryErrorKind::PackageElementAbsent {
166                package,
167                version,
168                platform,
169                element,
170                path,
171            },
172        }
173    }
174}
175
176impl Display for RepositoryError {
177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178        write!(f, "R{:04}: {}", self.id, self.kind)
179    }
180}
181
182impl CommonRepositoryError for RepositoryError {}
183
184pub type RepositoryResult<T> = Result<T, RepositoryError>;