refactor for stronger RawPduId type

implement standard traits for PduCount

enable serde for arrayvec

typedef various shortid's

pducount simplifications

split parts of pdu_metadata service to core/pdu and api/relations

remove some yields; improve var names/syntax

tweak types for limit timeline limit arguments

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-11-02 06:12:54 +00:00
parent 2e4d9cb37c
commit 9da523c004
41 changed files with 796 additions and 573 deletions

View file

@ -1,38 +1,135 @@
use std::cmp::Ordering;
#![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss, clippy::as_conversions)]
use ruma::api::client::error::ErrorKind;
use std::{cmp::Ordering, fmt, fmt::Display, str::FromStr};
use crate::{Error, Result};
use crate::{err, Error, Result};
#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
pub enum PduCount {
Backfilled(u64),
Normal(u64),
Backfilled(i64),
}
impl PduCount {
#[inline]
#[must_use]
pub fn min() -> Self { Self::Backfilled(u64::MAX) }
pub fn from_unsigned(unsigned: u64) -> Self { Self::from_signed(unsigned as i64) }
#[inline]
#[must_use]
pub fn max() -> Self { Self::Normal(u64::MAX) }
pub fn try_from_string(token: &str) -> Result<Self> {
if let Some(stripped_token) = token.strip_prefix('-') {
stripped_token.parse().map(PduCount::Backfilled)
} else {
token.parse().map(PduCount::Normal)
pub fn from_signed(signed: i64) -> Self {
match signed {
i64::MIN..=0 => Self::Backfilled(signed),
_ => Self::Normal(signed as u64),
}
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid pagination token."))
}
#[inline]
#[must_use]
pub fn stringify(&self) -> String {
pub fn into_unsigned(self) -> u64 {
self.debug_assert_valid();
match self {
Self::Backfilled(x) => format!("-{x}"),
Self::Normal(x) => x.to_string(),
Self::Normal(i) => i,
Self::Backfilled(i) => i as u64,
}
}
#[inline]
#[must_use]
pub fn into_signed(self) -> i64 {
self.debug_assert_valid();
match self {
Self::Normal(i) => i as i64,
Self::Backfilled(i) => i,
}
}
#[inline]
#[must_use]
pub fn into_normal(self) -> Self {
self.debug_assert_valid();
match self {
Self::Normal(i) => Self::Normal(i),
Self::Backfilled(_) => Self::Normal(0),
}
}
#[inline]
pub fn checked_add(self, add: u64) -> Result<Self, Error> {
Ok(match self {
Self::Normal(i) => Self::Normal(
i.checked_add(add)
.ok_or_else(|| err!(Arithmetic("PduCount::Normal overflow")))?,
),
Self::Backfilled(i) => Self::Backfilled(
i.checked_add(add as i64)
.ok_or_else(|| err!(Arithmetic("PduCount::Backfilled overflow")))?,
),
})
}
#[inline]
pub fn checked_sub(self, sub: u64) -> Result<Self, Error> {
Ok(match self {
Self::Normal(i) => Self::Normal(
i.checked_sub(sub)
.ok_or_else(|| err!(Arithmetic("PduCount::Normal underflow")))?,
),
Self::Backfilled(i) => Self::Backfilled(
i.checked_sub(sub as i64)
.ok_or_else(|| err!(Arithmetic("PduCount::Backfilled underflow")))?,
),
})
}
#[inline]
#[must_use]
pub fn saturating_add(self, add: u64) -> Self {
match self {
Self::Normal(i) => Self::Normal(i.saturating_add(add)),
Self::Backfilled(i) => Self::Backfilled(i.saturating_add(add as i64)),
}
}
#[inline]
#[must_use]
pub fn saturating_sub(self, sub: u64) -> Self {
match self {
Self::Normal(i) => Self::Normal(i.saturating_sub(sub)),
Self::Backfilled(i) => Self::Backfilled(i.saturating_sub(sub as i64)),
}
}
#[inline]
#[must_use]
pub fn min() -> Self { Self::Backfilled(i64::MIN) }
#[inline]
#[must_use]
pub fn max() -> Self { Self::Normal(i64::MAX as u64) }
#[inline]
pub(crate) fn debug_assert_valid(&self) {
if let Self::Backfilled(i) = self {
debug_assert!(*i <= 0, "Backfilled sequence must be negative");
}
}
}
impl Display for PduCount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.debug_assert_valid();
match self {
Self::Normal(i) => write!(f, "{i}"),
Self::Backfilled(i) => write!(f, "{i}"),
}
}
}
impl FromStr for PduCount {
type Err = Error;
fn from_str(token: &str) -> Result<Self, Self::Err> { Ok(Self::from_signed(token.parse()?)) }
}
impl PartialOrd for PduCount {
@ -40,12 +137,9 @@ impl PartialOrd for PduCount {
}
impl Ord for PduCount {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Self::Normal(s), Self::Normal(o)) => s.cmp(o),
(Self::Backfilled(s), Self::Backfilled(o)) => o.cmp(s),
(Self::Normal(_), Self::Backfilled(_)) => Ordering::Greater,
(Self::Backfilled(_), Self::Normal(_)) => Ordering::Less,
}
}
fn cmp(&self, other: &Self) -> Ordering { self.into_signed().cmp(&other.into_signed()) }
}
impl Default for PduCount {
fn default() -> Self { Self::Normal(0) }
}