perspective_client/utils/
mod.rs

1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
5// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13//! Utility functions that are common to the Perspective crates.
14
15mod clone;
16mod logging;
17
18#[cfg(test)]
19mod tests;
20
21use thiserror::*;
22
23use crate::proto;
24
25#[derive(Error, Debug)]
26pub enum ClientError {
27    #[error("View not found")]
28    ViewNotFound,
29
30    #[error("Abort(): {0}")]
31    Internal(String),
32
33    #[error("Client not yet initialized")]
34    NotInitialized,
35
36    #[error("Unknown error: {0}")]
37    Unknown(String),
38
39    #[error("Unwrapped option")]
40    Option,
41
42    #[error("Unexpected response {0:?}")]
43    OptionResponseFailed(Box<Option<proto::response::ClientResp>>),
44
45    #[error("Bad string")]
46    Utf8(#[from] std::str::Utf8Error),
47
48    #[error("Undecipherable server message {0:?}")]
49    DecodeError(#[from] prost::DecodeError),
50
51    #[error("Unexpected response {0:?}")]
52    ResponseFailed(Box<proto::response::ClientResp>),
53
54    #[error("Not yet implemented {0:?}")]
55    NotImplemented(&'static str),
56
57    #[error("Can't use both `limit` and `index` arguments")]
58    BadTableOptions,
59
60    #[error("External error: {0}")]
61    ExternalError(#[from] Box<dyn std::error::Error + Send + Sync>),
62
63    #[error("Undecipherable proto message")]
64    ProtoError(#[from] prost::EncodeError),
65}
66
67pub type ClientResult<T> = Result<T, ClientError>;
68
69impl From<proto::response::ClientResp> for ClientError {
70    fn from(value: proto::response::ClientResp) -> Self {
71        match value {
72            proto::response::ClientResp::ServerError(x) => match x.status_code() {
73                proto::StatusCode::ServerError => ClientError::Internal(x.message),
74                proto::StatusCode::ViewNotFound => ClientError::ViewNotFound,
75            },
76            x => ClientError::ResponseFailed(Box::new(x)),
77        }
78    }
79}
80
81pub trait PerspectiveResultExt {
82    fn unwrap_or_log(&self);
83}
84
85impl<T, E> PerspectiveResultExt for Result<T, E>
86where
87    E: std::error::Error,
88{
89    fn unwrap_or_log(&self) {
90        if let Err(e) = self {
91            tracing::warn!("{}", e);
92        }
93    }
94}