1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::cell::RefCell;
use std::error::Error;
use std::fs::{self, File, OpenOptions};
use std::io::{Read, Seek, SeekFrom, Write};
use std::os::unix::fs::PermissionsExt;
use std::os::unix::io::{AsRawFd, RawFd};
use std::rc::Rc;
use std::string::String;
use crate::{Ev3Error, Ev3Result};
const ROOT_PATH: &str = "/sys/class/";
#[derive(Debug, Clone)]
pub struct Attribute {
file: Rc<RefCell<File>>,
}
impl Attribute {
pub fn new(class_name: &str, name: &str, attribute_name: &str) -> Ev3Result<Attribute> {
let filename = format!("{}{}/{}/{}", ROOT_PATH, class_name, name, attribute_name);
let stat = fs::metadata(&filename)?;
let mode = stat.permissions().mode();
let readable = mode & 256 == 256;
let writeable = mode & 128 == 128;
let file = OpenOptions::new()
.read(readable)
.write(writeable)
.open(&filename)?;
Ok(Attribute {
file: Rc::new(RefCell::new(file)),
})
}
fn get_str(&self) -> Ev3Result<String> {
let mut value = String::new();
let mut file = self.file.borrow_mut();
file.seek(SeekFrom::Start(0))?;
file.read_to_string(&mut value)?;
Ok(value.trim_end().to_owned())
}
fn set_str(&self, value: &str) -> Ev3Result<()> {
let mut file = self.file.borrow_mut();
file.seek(SeekFrom::Start(0))?;
file.write_all(value.as_bytes())?;
Ok(())
}
pub fn get<T>(&self) -> Ev3Result<T>
where
T: std::str::FromStr,
<T as std::str::FromStr>::Err: Error,
{
let value = self.get_str()?;
match value.parse::<T>() {
Ok(value) => Ok(value),
Err(e) => Err(Ev3Error::InternalError {
msg: format!("{}", e),
}),
}
}
pub fn set<T>(&self, value: T) -> Ev3Result<()>
where
T: std::string::ToString,
{
self.set_str(&value.to_string())
}
#[inline]
pub fn set_str_slice(&self, value: &str) -> Ev3Result<()> {
self.set_str(value)
}
pub fn get_vec(&self) -> Ev3Result<Vec<String>> {
let value = self.get_str()?;
let vec = value
.split_whitespace()
.map(|word| word.to_owned())
.collect();
Ok(vec)
}
pub fn get_raw_fd(&self) -> RawFd {
self.file.borrow().as_raw_fd()
}
}