usb_gadget/function/
other.rs1use std::{
4 collections::HashMap,
5 ffi::{OsStr, OsString},
6 io::{Error, ErrorKind, Result},
7 os::unix::prelude::OsStrExt,
8 path::{Component, Path, PathBuf},
9};
10
11use super::{
12 util::{FunctionDir, Status},
13 Function, Handle,
14};
15
16#[derive(Debug, Clone)]
18pub struct OtherBuilder {
19 driver: OsString,
21 properties: HashMap<PathBuf, Vec<u8>>,
23}
24
25impl OtherBuilder {
26 #[must_use]
30 pub fn build(self) -> (Other, Handle) {
31 let dir = FunctionDir::new();
32 (Other { dir: dir.clone() }, Handle::new(OtherFunction { builder: self, dir }))
33 }
34
35 pub fn set(&mut self, name: impl AsRef<Path>, value: impl AsRef<[u8]>) -> Result<()> {
37 let path = name.as_ref().to_path_buf();
38 if !path.components().all(|c| matches!(c, Component::Normal(_))) {
39 return Err(Error::new(ErrorKind::InvalidInput, "property path must be relative"));
40 }
41
42 self.properties.insert(path, value.as_ref().to_vec());
43 Ok(())
44 }
45}
46
47#[derive(Debug)]
48struct OtherFunction {
49 builder: OtherBuilder,
50 dir: FunctionDir,
51}
52
53impl Function for OtherFunction {
54 fn driver(&self) -> OsString {
55 self.builder.driver.clone()
56 }
57
58 fn dir(&self) -> FunctionDir {
59 self.dir.clone()
60 }
61
62 fn register(&self) -> Result<()> {
63 for (prop, val) in &self.builder.properties {
64 self.dir.write(prop, val)?;
65 }
66
67 Ok(())
68 }
69}
70
71#[derive(Debug)]
75pub struct Other {
76 dir: FunctionDir,
77}
78
79impl Other {
80 pub fn new(driver: impl AsRef<OsStr>) -> Result<(Other, Handle)> {
82 Ok(Self::builder(driver)?.build())
83 }
84
85 pub fn builder(driver: impl AsRef<OsStr>) -> Result<OtherBuilder> {
87 let driver = driver.as_ref();
88 if driver.as_bytes().contains(&b'.') || driver.as_bytes().contains(&b'/') || !driver.is_ascii() {
89 return Err(Error::new(ErrorKind::InvalidInput, "invalid driver name"));
90 }
91
92 Ok(OtherBuilder { driver: driver.to_os_string(), properties: HashMap::new() })
93 }
94
95 pub fn status(&self) -> Status {
97 self.dir.status()
98 }
99
100 pub fn get(&self, name: impl AsRef<Path>) -> Result<Vec<u8>> {
102 self.dir.read(name)
103 }
104}