rustfst/semirings/
integer_weight.rs1use nom::character::complete::i32;
2use std::{borrow::Borrow, io::Write};
3
4use anyhow::Result;
5use nom::IResult;
6
7use crate::{
8 parsers::{parse_bin_i32, write_bin_i32},
9 semirings::{CompleteSemiring, ReverseBack, Semiring, SemiringProperties, StarSemiring},
10 NomCustomError,
11};
12
13use super::SerializableSemiring;
14
15#[derive(Clone, Debug, PartialEq, PartialOrd, Default, Hash, Eq, Copy)]
17pub struct IntegerWeight {
18 value: i32,
19}
20
21impl Semiring for IntegerWeight {
22 type Type = i32;
23 type ReverseWeight = IntegerWeight;
24
25 fn zero() -> Self {
26 Self { value: 0 }
27 }
28 fn one() -> Self {
29 Self { value: 1 }
30 }
31
32 fn new(value: <Self as Semiring>::Type) -> Self {
33 IntegerWeight { value }
34 }
35
36 fn plus_assign<P: Borrow<Self>>(&mut self, rhs: P) -> Result<()> {
37 self.value += rhs.borrow().value;
38 Ok(())
39 }
40
41 fn times_assign<P: Borrow<Self>>(&mut self, rhs: P) -> Result<()> {
42 self.value *= rhs.borrow().value;
43 Ok(())
44 }
45
46 fn approx_equal<P: Borrow<Self>>(&self, rhs: P, _delta: f32) -> bool {
47 self.value == rhs.borrow().value
48 }
49
50 fn value(&self) -> &Self::Type {
51 &self.value
52 }
53
54 fn take_value(self) -> Self::Type {
55 self.value
56 }
57
58 fn set_value(&mut self, value: <Self as Semiring>::Type) {
59 self.value = value
60 }
61
62 fn reverse(&self) -> Result<Self::ReverseWeight> {
63 Ok(*self)
64 }
65
66 fn properties() -> SemiringProperties {
67 SemiringProperties::LEFT_SEMIRING
68 | SemiringProperties::RIGHT_SEMIRING
69 | SemiringProperties::COMMUTATIVE
70 }
71}
72
73impl ReverseBack<IntegerWeight> for IntegerWeight {
74 fn reverse_back(&self) -> Result<IntegerWeight> {
75 Ok(*self)
76 }
77}
78
79impl AsRef<IntegerWeight> for IntegerWeight {
80 fn as_ref(&self) -> &IntegerWeight {
81 self
82 }
83}
84
85display_semiring!(IntegerWeight);
86
87impl CompleteSemiring for IntegerWeight {}
88
89impl StarSemiring for IntegerWeight {
90 fn closure(&self) -> Self {
91 if self.value == 0 {
92 return Self::new(1);
93 }
94 Self::new(i32::MAX)
95 }
96}
97
98impl From<i32> for IntegerWeight {
99 fn from(i: i32) -> Self {
100 Self::new(i)
101 }
102}
103
104impl SerializableSemiring for IntegerWeight {
105 fn weight_type() -> String {
106 "integer".to_string()
107 }
108
109 fn parse_binary(i: &[u8]) -> IResult<&[u8], Self, NomCustomError<&[u8]>> {
110 let (i, weight) = parse_bin_i32(i)?;
111 Ok((i, Self::new(weight)))
112 }
113
114 fn write_binary<F: Write>(&self, file: &mut F) -> Result<()> {
115 write_bin_i32(file, *self.value())
116 }
117
118 fn parse_text(i: &str) -> IResult<&str, Self> {
119 let (i, f) = i32(i)?;
120 Ok((i, Self::new(f)))
121 }
122}
123
124test_semiring_serializable!(
125 tests_integer_weight_serializable,
126 IntegerWeight,
127 IntegerWeight::one() IntegerWeight::zero() IntegerWeight::new(3) IntegerWeight::new(5) IntegerWeight::new(10) IntegerWeight::new(100)
128);