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>;