taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

api_common.rs (3679B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 
     17 use std::{fmt::Display, ops::Deref};
     18 
     19 use rand_core::OsRng;
     20 use serde::{Deserialize, Deserializer, Serialize, de::Error};
     21 use serde_json::value::RawValue;
     22 
     23 use crate::types::base32::Base32;
     24 
     25 /// <https://docs.taler.net/core/api-common.html#tsref-type-ErrorDetail>
     26 #[derive(Debug, Clone, Serialize, Deserialize)]
     27 pub struct ErrorDetail {
     28     pub code: u32,
     29     pub hint: Option<Box<str>>,
     30     pub detail: Option<Box<str>>,
     31     pub parameter: Option<Box<str>>,
     32     pub path: Option<Box<str>>,
     33     pub offset: Option<Box<str>>,
     34     pub index: Option<Box<str>>,
     35     pub object: Option<Box<str>>,
     36     pub currency: Option<Box<str>>,
     37     pub type_expected: Option<Box<str>>,
     38     pub type_actual: Option<Box<str>>,
     39     pub extra: Option<Box<RawValue>>,
     40 }
     41 
     42 pub fn safe_u64(nb: u64) -> SafeU64 {
     43     SafeU64::try_from(nb).expect("invalid safe u64")
     44 }
     45 
     46 /// <https://docs.taler.net/core/api-common.html#tsref-type-SafeUint64>
     47 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
     48 pub struct SafeU64(u64);
     49 
     50 impl Deref for SafeU64 {
     51     type Target = u64;
     52 
     53     fn deref(&self) -> &Self::Target {
     54         &self.0
     55     }
     56 }
     57 
     58 #[derive(Debug, thiserror::Error)]
     59 pub enum SafeU64Error {
     60     #[error("{0} unsafe, {0} > (2^53 - 1)")]
     61     Unsafe(u64),
     62     #[error("{0} is negative")]
     63     Negative(i64),
     64 }
     65 
     66 impl TryFrom<u64> for SafeU64 {
     67     type Error = SafeU64Error;
     68 
     69     fn try_from(nb: u64) -> Result<Self, Self::Error> {
     70         if nb < (1 << 53) - 1 {
     71             Ok(SafeU64(nb))
     72         } else {
     73             Err(SafeU64Error::Unsafe(nb))
     74         }
     75     }
     76 }
     77 
     78 impl TryFrom<i64> for SafeU64 {
     79     type Error = SafeU64Error;
     80 
     81     fn try_from(nb: i64) -> Result<Self, Self::Error> {
     82         u64::try_from(nb)
     83             .map_err(|_| SafeU64Error::Negative(nb))
     84             .and_then(|it| it.try_into())
     85     }
     86 }
     87 
     88 impl TryFrom<i32> for SafeU64 {
     89     type Error = SafeU64Error;
     90 
     91     fn try_from(nb: i32) -> Result<Self, Self::Error> {
     92         u64::try_from(nb)
     93             .map_err(|_| SafeU64Error::Negative(nb as i64))
     94             .and_then(|it| it.try_into())
     95     }
     96 }
     97 
     98 impl<'de> Deserialize<'de> for SafeU64 {
     99     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    100     where
    101         D: Deserializer<'de>,
    102     {
    103         SafeU64::try_from(u64::deserialize(deserializer)?).map_err(D::Error::custom)
    104     }
    105 }
    106 
    107 impl Display for SafeU64 {
    108     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    109         self.0.fmt(f)
    110     }
    111 }
    112 
    113 /// EdDSA and ECDHE public keys always point on Curve25519
    114 /// and represented  using the standard 256 bits Ed25519 compact format,
    115 /// converted to Crockford Base32.
    116 pub type EddsaPublicKey = Base32<32>;
    117 /// 64-byte hash code
    118 pub type HashCode = Base32<64>;
    119 /// 32-bytes hash code
    120 pub type ShortHashCode = Base32<32>;
    121 pub type WadId = Base32<24>;
    122 
    123 pub fn rand_edsa_pub_key() -> EddsaPublicKey {
    124     let signing_key = ed25519_dalek::SigningKey::generate(&mut OsRng);
    125     Base32::from(signing_key.verifying_key().to_bytes())
    126 }