kernel/device/char/
mod.rs

1use core::any::Any;
2
3use alloc::{boxed::Box, vec::Vec};
4
5use super::Device;
6
7extern crate alloc;
8
9/// Character device interface
10/// 
11/// This trait defines the interface for character devices.
12/// It provides methods for querying device information and handling character I/O operations.
13pub trait CharDevice: Device {
14    /// Read a single byte from the device
15    /// 
16    /// # Returns
17    /// 
18    /// The byte read from the device, or None if no data is available
19    fn read_byte(&mut self) -> Option<u8>;
20    
21    /// Write a single byte to the device
22    /// 
23    /// # Arguments
24    /// 
25    /// * `byte` - The byte to write to the device
26    /// 
27    /// # Returns
28    /// 
29    /// Result indicating success or failure
30    fn write_byte(&mut self, byte: u8) -> Result<(), &'static str>;
31    
32    /// Read multiple bytes from the device
33    /// 
34    /// # Arguments
35    /// 
36    /// * `buffer` - The buffer to read data into
37    /// 
38    /// # Returns
39    /// 
40    /// The number of bytes actually read
41    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    /// Write multiple bytes to the device
55    /// 
56    /// # Arguments
57    /// 
58    /// * `buffer` - The buffer containing data to write
59    /// 
60    /// # Returns
61    /// 
62    /// Result containing the number of bytes written or an error
63    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    /// Check if the device is ready for reading
73    fn can_read(&self) -> bool;
74    
75    /// Check if the device is ready for writing
76    fn can_write(&self) -> bool;
77}
78
79/// A generic implementation of a character device
80pub 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;