cat_dev/fsemul/pcfs/sata/proto/
open_folder.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 SataOpenFolderPacketBody {
13 path: String,
24}
25
26impl SataOpenFolderPacketBody {
27 pub fn new(path: String) -> Result<Self, PcfsApiError> {
38 if path.len() > 511 {
39 return Err(PcfsApiError::PathTooLong(path));
40 }
41
42 Ok(Self { path })
43 }
44
45 #[must_use]
46 pub fn path(&self) -> &str {
47 self.path.as_str()
48 }
49
50 pub fn set_path(&mut self, new_path: String) -> Result<(), PcfsApiError> {
61 if new_path.len() > 511 {
62 return Err(PcfsApiError::PathTooLong(new_path));
63 }
64
65 self.path = new_path;
66 Ok(())
67 }
68}
69
70impl From<&SataOpenFolderPacketBody> for Bytes {
71 fn from(value: &SataOpenFolderPacketBody) -> Self {
72 let mut result = BytesMut::with_capacity(0x200);
73 result.extend_from_slice(value.path.as_bytes());
74 result.extend(BytesMut::zeroed(0x200 - result.len()));
77 result.freeze()
78 }
79}
80
81impl From<SataOpenFolderPacketBody> for Bytes {
82 fn from(value: SataOpenFolderPacketBody) -> Self {
83 Self::from(&value)
84 }
85}
86
87impl TryFrom<Bytes> for SataOpenFolderPacketBody {
88 type Error = NetworkParseError;
89
90 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
91 if value.len() < 0x200 {
92 return Err(NetworkParseError::FieldNotLongEnough(
93 "SataOpenFolder",
94 "Body",
95 0x200,
96 value.len(),
97 value,
98 ));
99 }
100 if value.len() > 0x200 {
101 return Err(NetworkParseError::UnexpectedTrailer(
102 "SataOpenFolder",
103 value.slice(0x200..),
104 ));
105 }
106
107 let path_c_str =
108 CStr::from_bytes_until_nul(&value).map_err(NetworkParseError::BadCString)?;
109
110 Ok(Self {
111 path: path_c_str.to_str()?.to_owned(),
112 })
113 }
114}
115
116const SATA_OPEN_FOLDER_PACKET_BODY_FIELDS: &[NamedField<'static>] = &[NamedField::new("path")];
117
118impl Structable for SataOpenFolderPacketBody {
119 fn definition(&self) -> StructDef<'_> {
120 StructDef::new_static(
121 "SataOpenFolderPacketBody",
122 Fields::Named(SATA_OPEN_FOLDER_PACKET_BODY_FIELDS),
123 )
124 }
125}
126
127impl Valuable for SataOpenFolderPacketBody {
128 fn as_value(&self) -> Value<'_> {
129 Value::Structable(self)
130 }
131
132 fn visit(&self, visitor: &mut dyn Visit) {
133 visitor.visit_named_fields(&NamedValues::new(
134 SATA_OPEN_FOLDER_PACKET_BODY_FIELDS,
135 &[Valuable::as_value(&self.path)],
136 ));
137 }
138}