cat_dev/fsemul/pcfs/sata/proto/
remove.rs1use crate::{errors::NetworkParseError, fsemul::pcfs::errors::PcfsApiError};
8use bytes::{Bytes, BytesMut};
9use std::ffi::CStr;
10use valuable::{Fields, NamedField, NamedValues, StructDef, Structable, Valuable, Value, Visit};
11
12#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct SataRemovePacketBody {
15 path: String,
26}
27
28impl SataRemovePacketBody {
29 pub fn new(path: String) -> Result<Self, PcfsApiError> {
40 if path.len() > 511 {
41 return Err(PcfsApiError::PathTooLong(path));
42 }
43
44 Ok(Self { path })
45 }
46
47 #[must_use]
48 pub fn path(&self) -> &str {
49 self.path.as_str()
50 }
51
52 pub fn set_path(&mut self, new_path: String) -> Result<(), PcfsApiError> {
63 if new_path.len() > 511 {
64 return Err(PcfsApiError::PathTooLong(new_path));
65 }
66
67 self.path = new_path;
68 Ok(())
69 }
70}
71
72impl From<&SataRemovePacketBody> for Bytes {
73 fn from(value: &SataRemovePacketBody) -> Self {
74 let mut result = BytesMut::with_capacity(0x200);
75 result.extend_from_slice(value.path.as_bytes());
76 result.extend(BytesMut::zeroed(0x200 - result.len()));
79 result.freeze()
80 }
81}
82
83impl From<SataRemovePacketBody> for Bytes {
84 fn from(value: SataRemovePacketBody) -> Self {
85 Self::from(&value)
86 }
87}
88
89impl TryFrom<Bytes> for SataRemovePacketBody {
90 type Error = NetworkParseError;
91
92 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
93 if value.len() < 0x200 {
94 return Err(NetworkParseError::FieldNotLongEnough(
95 "SataRemove",
96 "Body",
97 0x200,
98 value.len(),
99 value,
100 ));
101 }
102 if value.len() > 0x200 {
103 return Err(NetworkParseError::UnexpectedTrailer(
104 "SataRemove",
105 value.slice(0x200..),
106 ));
107 }
108
109 let path_c_str =
110 CStr::from_bytes_until_nul(&value).map_err(NetworkParseError::BadCString)?;
111
112 Ok(Self {
113 path: path_c_str.to_str()?.to_owned(),
114 })
115 }
116}
117
118const SATA_REMOVE_PACKET_BODY_FIELDS: &[NamedField<'static>] = &[NamedField::new("path")];
119
120impl Structable for SataRemovePacketBody {
121 fn definition(&self) -> StructDef<'_> {
122 StructDef::new_static(
123 "SataRemovePacketBody",
124 Fields::Named(SATA_REMOVE_PACKET_BODY_FIELDS),
125 )
126 }
127}
128
129impl Valuable for SataRemovePacketBody {
130 fn as_value(&self) -> Value<'_> {
131 Value::Structable(self)
132 }
133
134 fn visit(&self, visitor: &mut dyn Visit) {
135 visitor.visit_named_fields(&NamedValues::new(
136 SATA_REMOVE_PACKET_BODY_FIELDS,
137 &[Valuable::as_value(&self.path)],
138 ));
139 }
140}