1use rmpv::Value;
2use std::io;
3use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum RpcError {
8 #[error("I/O error: {0}")]
10 Io(io::Error),
11
12 #[error("Serialization error: {0}")]
14 Serialization(#[from] rmpv::encode::Error),
15
16 #[error("Deserialization error: {0}")]
18 Deserialization(#[from] rmpv::decode::Error),
19
20 #[error("Protocol error: {0}")]
22 Protocol(String),
23
24 #[error("Service error: {0}")]
26 Service(ServiceError),
27
28 #[error("Connection disconnected")]
29 Disconnect,
30
31 #[error("Failed to connect to {0}")]
33 Connect(String),
34}
35
36#[derive(Error, Debug)]
43pub struct ServiceError {
44 pub name: String,
45 pub value: Value,
46}
47
48impl std::fmt::Display for ServiceError {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "Service error {}: {:?}", self.name, self.value)
51 }
52}
53
54impl From<ServiceError> for Value {
55 fn from(error: ServiceError) -> Self {
56 Value::Map(vec![
57 (
58 Value::String("name".into()),
59 Value::String(error.name.into()),
60 ),
61 (Value::String("value".into()), error.value),
62 ])
63 }
64}
65
66impl From<std::io::Error> for RpcError {
67 fn from(error: std::io::Error) -> Self {
68 if error.kind() == std::io::ErrorKind::UnexpectedEof {
69 RpcError::Disconnect
70 } else {
71 RpcError::Io(error)
72 }
73 }
74}
75
76pub type Result<T> = std::result::Result<T, RpcError>;