paper_client/
error.rs

1/*
2 * Copyright (c) Kia Shakiba
3 *
4 * This source code is licensed under the GNU AGPLv3 license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8use thiserror::Error;
9use paper_utils::stream::StreamReader;
10
11#[derive(Debug, PartialEq, Error)]
12pub enum PaperClientError {
13	#[error(transparent)]
14	ServerError(#[from] PaperServerError),
15
16	#[error(transparent)]
17	CacheError(#[from] PaperCacheError),
18
19	#[error("invalid PaperCache address")]
20	InvalidAddress,
21
22	#[error("could not connect to PaperServer")]
23	UnreachableServer,
24
25	#[error("could not send command to PaperServer")]
26	InvalidCommand,
27
28	#[error("could not parse supplied value as PaperValue")]
29	InvalidValue,
30
31	#[error("could not receive response from PaperServer")]
32	InvalidResponse,
33
34	#[error("an internal error occurred")]
35	Internal,
36
37	#[error("disconnected from PaperServer")]
38	Disconnected,
39}
40
41#[derive(Debug, PartialEq, Error)]
42pub enum PaperCacheError {
43	#[error("an internal error occurred")]
44	Internal,
45
46	#[error("the key was not found in the cache")]
47	KeyNotFound,
48
49	#[error("the value size cannot be zero")]
50	ZeroValueSize,
51
52	#[error("the value size cannot exceed the cache size")]
53	ExceedingValueSize,
54
55	#[error("the cache size cannot be zero")]
56	ZeroCacheSize,
57
58	#[error("unconfigured policy")]
59	UnconfiguredPolicy,
60
61	#[error("invalid policy")]
62	InvalidPolicy,
63}
64
65#[derive(Debug, PartialEq, Error)]
66pub enum PaperServerError {
67	#[error("an internal error occurred")]
68	Internal,
69
70	#[error("the maximum number of connections was exceeded")]
71	MaxConnectionsExceeded,
72
73	#[error("unauthorized")]
74	Unauthorized,
75}
76
77impl PaperClientError {
78	pub fn from_stream(mut reader: StreamReader) -> Self {
79		let Ok(code) = reader.read_u8() else {
80			return PaperClientError::InvalidResponse;
81		};
82
83		if code == 0 {
84			let Ok(cache_code) = reader.read_u8() else {
85				return PaperClientError::InvalidResponse;
86			};
87
88			let cache_error = PaperCacheError::from_code(cache_code);
89
90			return PaperClientError::CacheError(cache_error);
91		}
92
93		let server_error = PaperServerError::from_code(code);
94
95		PaperClientError::ServerError(server_error)
96	}
97}
98
99impl PaperServerError {
100	fn from_code(code: u8) -> Self {
101		match code {
102			2 => PaperServerError::MaxConnectionsExceeded,
103			3 => PaperServerError::Unauthorized,
104
105			_ => PaperServerError::Internal,
106		}
107	}
108}
109
110impl PaperCacheError {
111	fn from_code(code: u8) -> Self {
112		match code {
113			1 => PaperCacheError::KeyNotFound,
114
115			2 => PaperCacheError::ZeroValueSize,
116			3 => PaperCacheError::ExceedingValueSize,
117
118			4 => PaperCacheError::ZeroCacheSize,
119
120			5 => PaperCacheError::UnconfiguredPolicy,
121			6 => PaperCacheError::InvalidPolicy,
122
123			_ => PaperCacheError::Internal,
124		}
125	}
126}