1use bee_common::packable::Packable;
5
6use serde::{Deserialize, Serialize};
7
8use std::io::{Read, Write};
9
10#[derive(Debug, thiserror::Error)]
12pub enum ConflictError {
13 #[error("I/O error: {0}")]
15 Io(#[from] std::io::Error),
16 #[error("Invalid conflict byte")]
18 InvalidConflict(u8),
19}
20
21#[repr(u8)]
23#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
24pub enum ConflictReason {
25 None = 0,
27 InputUtxoAlreadySpent = 1,
29 InputUtxoAlreadySpentInThisMilestone = 2,
31 InputUtxoNotFound = 3,
33 InputOutputSumMismatch = 4,
35 InvalidSignature = 5,
37 InvalidDustAllowance = 6,
39 SemanticValidationFailed = 255,
41}
42
43impl Default for ConflictReason {
44 fn default() -> Self {
45 Self::None
46 }
47}
48
49impl TryFrom<u8> for ConflictReason {
50 type Error = ConflictError;
51
52 fn try_from(c: u8) -> Result<Self, Self::Error> {
53 Ok(match c {
54 0 => Self::None,
55 1 => Self::InputUtxoAlreadySpent,
56 2 => Self::InputUtxoAlreadySpentInThisMilestone,
57 3 => Self::InputUtxoNotFound,
58 4 => Self::InputOutputSumMismatch,
59 5 => Self::InvalidSignature,
60 6 => Self::InvalidDustAllowance,
61 255 => Self::SemanticValidationFailed,
62 x => return Err(Self::Error::InvalidConflict(x)),
63 })
64 }
65}
66
67impl Packable for ConflictReason {
68 type Error = ConflictError;
69
70 fn packed_len(&self) -> usize {
71 (*self as u8).packed_len()
72 }
73
74 fn pack<W: Write>(&self, writer: &mut W) -> Result<(), Self::Error> {
75 Ok((*self as u8).pack(writer)?)
76 }
77
78 fn unpack_inner<R: Read + ?Sized, const CHECK: bool>(reader: &mut R) -> Result<Self, Self::Error>
79 where
80 Self: Sized,
81 {
82 u8::unpack_inner::<R, CHECK>(reader)?.try_into()
83 }
84}