farmap 0.10.1

A library for working with Farcaster label datasets
Documentation
use crate::SpamScore;
use serde::Serialize;
use thiserror::Error;

#[derive(Serialize, Clone, Copy, PartialEq, Debug, Hash, Eq)]
pub struct FidScoreShift {
    source: ShiftSource,
    target: ShiftTarget,
    count: usize,
}

#[derive(Serialize, Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum ShiftSource {
    Zero,
    One,
    Two,
    New,
}

#[derive(Serialize, Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum ShiftTarget {
    Zero,
    One,
    Two,
    #[allow(dead_code)]
    Removed,
}

impl TryFrom<usize> for FidScoreShift {
    type Error = InvalidNumberError;

    fn try_from(value: usize) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(FidScoreShift::new(ShiftSource::Zero, ShiftTarget::Zero, 0)),
            1 => Ok(FidScoreShift::new(ShiftSource::Zero, ShiftTarget::One, 0)),
            2 => Ok(FidScoreShift::new(ShiftSource::Zero, ShiftTarget::Two, 0)),
            3 => Ok(FidScoreShift::new(ShiftSource::One, ShiftTarget::Zero, 0)),
            4 => Ok(FidScoreShift::new(ShiftSource::One, ShiftTarget::One, 0)),
            5 => Ok(FidScoreShift::new(ShiftSource::One, ShiftTarget::Two, 0)),
            6 => Ok(FidScoreShift::new(ShiftSource::Two, ShiftTarget::Zero, 0)),
            7 => Ok(FidScoreShift::new(ShiftSource::Two, ShiftTarget::One, 0)),
            8 => Ok(FidScoreShift::new(ShiftSource::Two, ShiftTarget::Two, 0)),
            9 => Ok(FidScoreShift::new(ShiftSource::New, ShiftTarget::Zero, 0)),
            10 => Ok(FidScoreShift::new(ShiftSource::New, ShiftTarget::One, 0)),
            11 => Ok(FidScoreShift::new(ShiftSource::New, ShiftTarget::Two, 0)),
            _ => Err(InvalidNumberError),
        }
    }
}

impl TryFrom<FidScoreShift> for usize {
    type Error = InvalidNumberError;
    fn try_from(value: FidScoreShift) -> Result<usize, Self::Error> {
        match (value.source(), value.target()) {
            (ShiftSource::Zero, ShiftTarget::Zero) => Ok(0),
            (ShiftSource::Zero, ShiftTarget::One) => Ok(1),
            (ShiftSource::Zero, ShiftTarget::Two) => Ok(2),
            (ShiftSource::One, ShiftTarget::Zero) => Ok(3),
            (ShiftSource::One, ShiftTarget::One) => Ok(4),
            (ShiftSource::One, ShiftTarget::Two) => Ok(5),
            (ShiftSource::Two, ShiftTarget::Zero) => Ok(6),
            (ShiftSource::Two, ShiftTarget::One) => Ok(7),
            (ShiftSource::Two, ShiftTarget::Two) => Ok(8),
            (ShiftSource::New, ShiftTarget::Zero) => Ok(9),
            (ShiftSource::New, ShiftTarget::One) => Ok(10),
            (ShiftSource::New, ShiftTarget::Two) => Ok(11),
            _ => Err(InvalidNumberError),
        }
    }
}

impl TryFrom<u8> for ShiftSource {
    type Error = InvalidNumberError;
    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::Zero),
            1 => Ok(Self::One),
            2 => Ok(Self::Two),
            3 => Ok(Self::New),
            _ => Err(InvalidNumberError),
        }
    }
}

impl TryFrom<u8> for ShiftTarget {
    type Error = InvalidNumberError;
    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::Zero),
            1 => Ok(Self::One),
            2 => Ok(Self::Two),
            3 => Ok(Self::Removed),
            _ => Err(InvalidNumberError),
        }
    }
}

impl From<SpamScore> for ShiftSource {
    fn from(value: SpamScore) -> Self {
        match value {
            SpamScore::Zero => ShiftSource::Zero,
            SpamScore::One => ShiftSource::One,
            SpamScore::Two => ShiftSource::Two,
        }
    }
}

impl From<SpamScore> for ShiftTarget {
    fn from(value: SpamScore) -> Self {
        match value {
            SpamScore::Zero => ShiftTarget::Zero,
            SpamScore::One => ShiftTarget::One,
            SpamScore::Two => ShiftTarget::Two,
        }
    }
}

#[derive(Error, Debug)]
#[error("number out of bounds, must be between 0 and 16")]
pub struct InvalidNumberError;

impl FidScoreShift {
    pub fn new(source: ShiftSource, target: ShiftTarget, count: usize) -> Self {
        Self {
            source,
            target,
            count,
        }
    }

    pub fn source(&self) -> ShiftSource {
        self.source
    }

    pub fn add(&mut self) {
        self.count += 1;
    }

    pub fn target(&self) -> ShiftTarget {
        self.target
    }

    pub fn count(&self) -> usize {
        self.count
    }

    pub fn increment(&mut self) {
        self.count += 1;
    }
}