ZIm/crates/git/src/stash.rs
Alvaro Parker 231a348e69
WIP
2025-08-21 11:39:59 -04:00

56 lines
1.7 KiB
Rust

use crate::Oid;
use anyhow::Result;
use std::{str::FromStr, sync::Arc};
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct StashEntry {
pub index: usize,
pub oid: Oid,
pub message: String,
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
pub struct GitStash {
pub entries: Arc<[StashEntry]>,
}
impl FromStr for GitStash {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
// git stash list --pretty=%gd:%H:%s
let entries = s
.split('\n')
.filter_map(|entry| {
let mut parts = entry.splitn(3, ':');
let raw_idx = parts.next().and_then(|i| {
let trimmed = i.trim();
if trimmed.starts_with("stash@{") && trimmed.ends_with('}') {
trimmed
.strip_prefix("stash@{")
.and_then(|s| s.strip_suffix('}'))
} else {
None
}
});
let raw_oid = parts.next();
let message = parts.next();
if let (Some(raw_idx), Some(raw_oid), Some(message)) = (raw_idx, raw_oid, message) {
let index = raw_idx.parse::<usize>().ok()?;
let oid = Oid::from_str(raw_oid).ok()?;
let entry = StashEntry {
index,
oid,
message: message.to_string(),
};
return Some(entry);
}
None
})
.collect::<Arc<[StashEntry]>>();
Ok(Self {
entries: entries.clone(),
})
}
}