kernel/device/char/
mod.rs1use core::any::Any;
2
3use alloc::{boxed::Box, vec::Vec};
4
5use super::Device;
6
7extern crate alloc;
8
9pub trait CharDevice: Device {
14 fn read_byte(&mut self) -> Option<u8>;
20
21 fn write_byte(&mut self, byte: u8) -> Result<(), &'static str>;
31
32 fn read(&mut self, buffer: &mut [u8]) -> usize {
42 let mut bytes_read = 0;
43 for i in 0..buffer.len() {
44 if let Some(byte) = self.read_byte() {
45 buffer[i] = byte;
46 bytes_read += 1;
47 } else {
48 break;
49 }
50 }
51 bytes_read
52 }
53
54 fn write(&mut self, buffer: &[u8]) -> Result<usize, &'static str> {
64 let mut bytes_written = 0;
65 for &byte in buffer {
66 self.write_byte(byte)?;
67 bytes_written += 1;
68 }
69 Ok(bytes_written)
70 }
71
72 fn can_read(&self) -> bool;
74
75 fn can_write(&self) -> bool;
77}
78
79pub struct GenericCharDevice {
81 id: usize,
82 device_name: &'static str,
83 read_fn: fn() -> Option<u8>,
84 write_fn: fn(u8) -> Result<(), &'static str>,
85 can_read_fn: fn() -> bool,
86 can_write_fn: fn() -> bool,
87}
88
89impl GenericCharDevice {
90 pub fn new(
91 id: usize,
92 device_name: &'static str,
93 read_fn: fn() -> Option<u8>,
94 write_fn: fn(u8) -> Result<(), &'static str>,
95 can_read_fn: fn() -> bool,
96 can_write_fn: fn() -> bool,
97 ) -> Self {
98 Self {
99 id,
100 device_name,
101 read_fn,
102 write_fn,
103 can_read_fn,
104 can_write_fn,
105 }
106 }
107}
108
109impl Device for GenericCharDevice {
110 fn device_type(&self) -> super::DeviceType {
111 super::DeviceType::Char
112 }
113
114 fn name(&self) -> &'static str {
115 self.device_name
116 }
117
118 fn id(&self) -> usize {
119 self.id
120 }
121
122 fn as_any(&self) -> &dyn Any {
123 self
124 }
125
126 fn as_any_mut(&mut self) -> &mut dyn Any {
127 self
128 }
129
130 fn as_char_device(&mut self) -> Option<&mut dyn CharDevice> {
131 Some(self)
132 }
133}
134
135impl CharDevice for GenericCharDevice {
136 fn read_byte(&mut self) -> Option<u8> {
137 (self.read_fn)()
138 }
139
140 fn write_byte(&mut self, byte: u8) -> Result<(), &'static str> {
141 (self.write_fn)(byte)
142 }
143
144 fn can_read(&self) -> bool {
145 (self.can_read_fn)()
146 }
147
148 fn can_write(&self) -> bool {
149 (self.can_write_fn)()
150 }
151}
152
153#[cfg(test)]
154mod tests;
155
156#[cfg(test)]
157pub mod mockchar;