use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GpioChipInfo {
pub chip: u32,
pub path: PathBuf,
pub label: String,
pub num_lines: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GpioLineInfo {
pub chip: u32,
pub line: u32,
pub name: Option<String>,
pub in_use: bool,
pub direction: Option<GpioDirection>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GpioDirection {
Input,
Output,
}
impl std::fmt::Display for GpioDirection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Input => write!(f, "input"),
Self::Output => write!(f, "output"),
}
}
}
pub fn discover_chips() -> Vec<GpioChipInfo> {
let mut chips = Vec::new();
for i in 0..16 {
let path = PathBuf::from(format!("/dev/gpiochip{i}"));
if path.exists() {
chips.push(GpioChipInfo {
chip: i,
path,
label: format!("gpiochip{i}"),
num_lines: 0, });
}
}
chips
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn gpio_direction_display() {
assert_eq!(GpioDirection::Input.to_string(), "input");
assert_eq!(GpioDirection::Output.to_string(), "output");
}
#[test]
fn gpio_chip_info_serialization() {
let info = GpioChipInfo {
chip: 0,
path: PathBuf::from("/dev/gpiochip0"),
label: "gpiochip0".to_string(),
num_lines: 32,
};
let json = serde_json::to_string(&info).unwrap();
let deserialized: GpioChipInfo = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.chip, 0);
}
}