cat_dev/fsemul/pcfs/sata/proto/
stat_file.rs

1//! Definitions for the `StatFile` packet type, and it's response types.
2//!
3//! This doesn't actually "handle" anything itself. As this is the same as
4//! `GetInfoByQuery` query type 5. So we just parse as a body, and then in
5//! the handler call query type 5.
6
7use crate::errors::NetworkParseError;
8use bytes::{Buf, BufMut, Bytes, BytesMut};
9use valuable::{Fields, NamedField, NamedValues, StructDef, Structable, Valuable, Value, Visit};
10
11/// A packet to get information about an open file handle.
12///
13/// This can do everything from "get the free space of the disk this path
14/// is on", to "get my some metadata about this very specific path."
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct SataStatFilePacketBody {
17	file_descriptor: i32,
18}
19
20impl SataStatFilePacketBody {
21	/// Create a new packet to STAT a particular file.
22	#[must_use]
23	pub const fn new(file_descriptor: i32) -> Self {
24		Self { file_descriptor }
25	}
26
27	#[must_use]
28	pub const fn file_descriptor(&self) -> i32 {
29		self.file_descriptor
30	}
31
32	pub const fn set_file_descriptor(&mut self, new_fd: i32) {
33		self.file_descriptor = new_fd;
34	}
35}
36
37impl From<&SataStatFilePacketBody> for Bytes {
38	fn from(value: &SataStatFilePacketBody) -> Self {
39		let mut buff = BytesMut::with_capacity(4);
40		buff.put_i32(value.file_descriptor);
41		buff.freeze()
42	}
43}
44
45impl From<SataStatFilePacketBody> for Bytes {
46	fn from(value: SataStatFilePacketBody) -> Self {
47		Self::from(&value)
48	}
49}
50
51impl TryFrom<Bytes> for SataStatFilePacketBody {
52	type Error = NetworkParseError;
53
54	fn try_from(mut value: Bytes) -> Result<Self, Self::Error> {
55		if value.len() < 0x4 {
56			return Err(NetworkParseError::FieldNotLongEnough(
57				"SataStatFile",
58				"Body",
59				0x4,
60				value.len(),
61				value,
62			));
63		}
64		if value.len() > 0x4 {
65			return Err(NetworkParseError::UnexpectedTrailer(
66				"SataStatFile",
67				value.slice(0x4..),
68			));
69		}
70
71		let fd = value.get_i32();
72
73		Ok(Self {
74			file_descriptor: fd,
75		})
76	}
77}
78
79const SATA_STAT_FILE_PACKET_BODY_FIELDS: &[NamedField<'static>] = &[NamedField::new("fd")];
80
81impl Structable for SataStatFilePacketBody {
82	fn definition(&self) -> StructDef<'_> {
83		StructDef::new_static(
84			"SataStatFilePacketBody",
85			Fields::Named(SATA_STAT_FILE_PACKET_BODY_FIELDS),
86		)
87	}
88}
89
90impl Valuable for SataStatFilePacketBody {
91	fn as_value(&self) -> Value<'_> {
92		Value::Structable(self)
93	}
94
95	fn visit(&self, visitor: &mut dyn Visit) {
96		visitor.visit_named_fields(&NamedValues::new(
97			SATA_STAT_FILE_PACKET_BODY_FIELDS,
98			&[Valuable::as_value(&self.file_descriptor)],
99		));
100	}
101}