Add missing SHELL build-arg
Change-Id: Ic645c0411928f8b69c4d5b21a90462170576e7bc
diff --git a/crates/passwd/Cargo.toml b/crates/passwd/Cargo.toml
new file mode 100644
index 0000000..25b3dc1
--- /dev/null
+++ b/crates/passwd/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "passwd"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+thiserror = "2.0.11"
diff --git a/crates/passwd/src/lib.rs b/crates/passwd/src/lib.rs
new file mode 100644
index 0000000..395a441
--- /dev/null
+++ b/crates/passwd/src/lib.rs
@@ -0,0 +1,81 @@
+use std::num::ParseIntError;
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum PasswdEntryError {
+ #[error("Failed to parse ID: {0}")]
+ FailedToParseID(#[from] ParseIntError),
+
+ #[error("Invalid passwd entry: {0}")]
+ InvalidPasswdEntry(String),
+}
+
+#[derive(Debug, Clone)]
+pub struct PasswdEntry {
+ pub name: String,
+ pub passwd: String,
+ pub uid: u32,
+ pub gid: u32,
+ pub gecos: String,
+ pub dir: String,
+ pub shell: String,
+}
+
+impl PasswdEntry {
+ pub fn from_line(line: &str) -> Result<PasswdEntry, PasswdEntryError> {
+ let parts: Vec<&str> = line.split(":").map(|part| part.trim()).collect();
+
+ if parts.len() != 7 {
+ return Err(PasswdEntryError::InvalidPasswdEntry(line.to_string()));
+ }
+
+ Ok(PasswdEntry {
+ name: parts[0].to_string(),
+ passwd: parts[1].to_string(),
+ uid: parts[2].parse()?,
+ gid: parts[3].parse()?,
+ gecos: parts[4].to_string(),
+ dir: parts[5].to_string(),
+ shell: parts[6].to_string(),
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_from_line_valid() {
+ let line = "username:x:1000:1000:User Name:/home/username:/bin/bash";
+ let entry = PasswdEntry::from_line(line).unwrap();
+ assert_eq!(entry.name, "username");
+ assert_eq!(entry.passwd, "x");
+ assert_eq!(entry.uid, 1000);
+ assert_eq!(entry.gid, 1000);
+ assert_eq!(entry.gecos, "User Name");
+ assert_eq!(entry.dir, "/home/username");
+ assert_eq!(entry.shell, "/bin/bash");
+ }
+
+ #[test]
+ fn test_from_line_invalid_uid() {
+ let line = "username:x:invalid:1000:User Name:/home/username:/bin/bash";
+ let result = PasswdEntry::from_line(line);
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn test_from_line_invalid_gid() {
+ let line = "username:x:1000:invalid:User Name:/home/username:/bin/bash";
+ let result = PasswdEntry::from_line(line);
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn test_from_line_missing_fields() {
+ let line = "username:x:1000:1000:User Name:/home/username";
+ let result = PasswdEntry::from_line(line);
+ assert!(result.is_err());
+ }
+}