use std::fmt;
use std::num::NonZeroUsize;
use std::time::SystemTime;
use stoffel_vm_types::core_types::{ShareData, ShareType};
use stoffelnet::network_utils::ClientId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct ClientInputIndex(usize);
impl ClientInputIndex {
pub const fn new(index: usize) -> Self {
Self(index)
}
pub const fn index(self) -> usize {
self.0
}
}
impl fmt::Display for ClientInputIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct ClientInputHydrationCount(usize);
impl ClientInputHydrationCount {
pub const ZERO: Self = Self(0);
pub const fn new(count: usize) -> Self {
Self(count)
}
pub const fn zero() -> Self {
Self::ZERO
}
pub const fn count(self) -> usize {
self.0
}
pub const fn is_zero(self) -> bool {
self.0 == 0
}
}
impl From<usize> for ClientInputHydrationCount {
fn from(count: usize) -> Self {
Self::new(count)
}
}
impl From<ClientInputHydrationCount> for usize {
fn from(count: ClientInputHydrationCount) -> Self {
count.count()
}
}
impl fmt::Display for ClientInputHydrationCount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct ClientShareIndex(usize);
impl ClientShareIndex {
pub const fn new(index: usize) -> Self {
Self(index)
}
pub const fn index(self) -> usize {
self.0
}
}
impl fmt::Display for ClientShareIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ClientOutputShareCount(NonZeroUsize);
impl ClientOutputShareCount {
pub const ONE: Self = Self(NonZeroUsize::MIN);
pub const fn new(count: NonZeroUsize) -> Self {
Self(count)
}
pub fn try_new(count: usize) -> Result<Self, ClientOutputShareCountError> {
NonZeroUsize::new(count)
.map(Self)
.ok_or(ClientOutputShareCountError)
}
pub const fn one() -> Self {
Self::ONE
}
pub const fn count(self) -> usize {
self.0.get()
}
pub const fn as_nonzero(self) -> NonZeroUsize {
self.0
}
}
impl Default for ClientOutputShareCount {
fn default() -> Self {
Self::one()
}
}
impl TryFrom<usize> for ClientOutputShareCount {
type Error = ClientOutputShareCountError;
fn try_from(count: usize) -> Result<Self, Self::Error> {
Self::try_new(count)
}
}
impl From<NonZeroUsize> for ClientOutputShareCount {
fn from(count: NonZeroUsize) -> Self {
Self::new(count)
}
}
impl fmt::Display for ClientOutputShareCount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ClientOutputShareCountError;
impl fmt::Display for ClientOutputShareCountError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("client output share count must be non-zero")
}
}
impl std::error::Error for ClientOutputShareCountError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ClientShare {
share_type: Option<ShareType>,
data: ShareData,
}
impl ClientShare {
pub fn untyped_bytes(bytes: Vec<u8>) -> Self {
Self {
share_type: None,
data: ShareData::Opaque(bytes.into()),
}
}
pub fn typed(share_type: ShareType, data: ShareData) -> Self {
Self {
share_type: Some(share_type),
data,
}
}
pub fn untyped(data: ShareData) -> Self {
Self {
share_type: None,
data,
}
}
pub fn share_type(&self) -> Option<ShareType> {
self.share_type
}
pub fn data(&self) -> &ShareData {
&self.data
}
pub fn into_data(self) -> ShareData {
self.data
}
pub fn bytes(&self) -> &[u8] {
self.data.as_bytes()
}
}
#[derive(Debug, Clone)]
pub struct ClientInputEntry {
pub client_id: ClientId,
pub shares: Vec<ClientShare>,
pub timestamp: SystemTime,
}