cat_dev/fsemul/pcfs/sata/proto/
rename.rs1use crate::{errors::NetworkParseError, fsemul::pcfs::errors::PcfsApiError};
6use bytes::{Bytes, BytesMut};
7use std::ffi::CStr;
8use valuable::{Fields, NamedField, NamedValues, StructDef, Structable, Valuable, Value, Visit};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct SataRenamePacketBody {
13 source_path: String,
15 dest_path: String,
17}
18
19impl SataRenamePacketBody {
20 pub fn new(source_path: String, dest_path: String) -> Result<Self, PcfsApiError> {
31 if source_path.len() > 511 {
32 return Err(PcfsApiError::PathTooLong(source_path));
33 }
34 if dest_path.len() > 511 {
35 return Err(PcfsApiError::PathTooLong(dest_path));
36 }
37
38 Ok(Self {
39 source_path,
40 dest_path,
41 })
42 }
43
44 #[must_use]
45 pub fn source_path(&self) -> &str {
46 self.source_path.as_str()
47 }
48
49 #[must_use]
50 pub fn dest_path(&self) -> &str {
51 self.dest_path.as_str()
52 }
53
54 pub fn set_source_path(&mut self, new_path: String) -> Result<(), PcfsApiError> {
65 if new_path.len() > 511 {
66 return Err(PcfsApiError::PathTooLong(new_path));
67 }
68
69 self.source_path = new_path;
70 Ok(())
71 }
72
73 pub fn set_dest_path(&mut self, new_path: String) -> Result<(), PcfsApiError> {
84 if new_path.len() > 511 {
85 return Err(PcfsApiError::PathTooLong(new_path));
86 }
87
88 self.dest_path = new_path;
89 Ok(())
90 }
91}
92
93impl TryFrom<Bytes> for SataRenamePacketBody {
94 type Error = NetworkParseError;
95
96 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
97 if value.len() < 0x400 {
98 return Err(NetworkParseError::FieldNotLongEnough(
99 "SataRenamePacketBody",
100 "Body",
101 0x400,
102 value.len(),
103 value,
104 ));
105 }
106 if value.len() > 0x400 {
107 return Err(NetworkParseError::UnexpectedTrailer(
108 "SataRenamePacketBody",
109 value.slice(0x400..),
110 ));
111 }
112
113 let source_path_c_str =
114 CStr::from_bytes_until_nul(&value[..0x200]).map_err(NetworkParseError::BadCString)?;
115 let dest_path_c_str =
116 CStr::from_bytes_until_nul(&value[0x200..]).map_err(NetworkParseError::BadCString)?;
117
118 Ok(Self {
119 source_path: source_path_c_str.to_str()?.to_owned(),
120 dest_path: dest_path_c_str.to_str()?.to_owned(),
121 })
122 }
123}
124
125impl From<&SataRenamePacketBody> for Bytes {
126 fn from(value: &SataRenamePacketBody) -> Self {
127 let mut result = BytesMut::with_capacity(0x400);
128 result.extend_from_slice(value.source_path.as_bytes());
129 result.extend(BytesMut::zeroed(0x200 - result.len()));
132 result.extend_from_slice(value.dest_path.as_bytes());
133 result.extend(BytesMut::zeroed(0x400 - result.len()));
135 result.freeze()
136 }
137}
138
139impl From<SataRenamePacketBody> for Bytes {
140 fn from(value: SataRenamePacketBody) -> Self {
141 Self::from(&value)
142 }
143}
144
145const SATA_RENAME_PACKET_BODY_FIELDS: &[NamedField<'static>] =
146 &[NamedField::new("source_path"), NamedField::new("dest_path")];
147
148impl Structable for SataRenamePacketBody {
149 fn definition(&self) -> StructDef<'_> {
150 StructDef::new_static(
151 "SataRenamePacketBody",
152 Fields::Named(SATA_RENAME_PACKET_BODY_FIELDS),
153 )
154 }
155}
156
157impl Valuable for SataRenamePacketBody {
158 fn as_value(&self) -> Value<'_> {
159 Value::Structable(self)
160 }
161
162 fn visit(&self, visitor: &mut dyn Visit) {
163 visitor.visit_named_fields(&NamedValues::new(
164 SATA_RENAME_PACKET_BODY_FIELDS,
165 &[
166 Valuable::as_value(&self.source_path),
167 Valuable::as_value(&self.dest_path),
168 ],
169 ));
170 }
171}