use crate::{chunk::Chunk, options::Options, providers::vcs::VcsTrait};
use crate::{
cmd::CMD,
providers::vcs::{merge_icons, StatusIcon},
};
use smallvec::SmallVec;
use smol_str::{SmolStr, ToSmolStr};
use std::convert::Infallible;
use std::{path::Path, str::FromStr};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Darcs;
macro_rules! darcs {
( $( $x:expr ),* ) => {
CMD.exec("darcs", [$( $x ),*])
};
}
impl VcsTrait for Darcs {
async fn branch(&self, _opts: &Options, _path: &Path) -> Option<Chunk<SmolStr>> {
None
}
async fn commit(&self, _opts: &Options, _path: &Path) -> Option<Chunk<SmolStr>> {
darcs!("log", "--last", "1", "--summary")
.await?
.lines()
.next()?
.split_whitespace()
.nth(1)
.map(|s| Chunk::new("⭑", s.trim().to_smolstr()))
}
async fn status(&self, _opts: &Options, _path: &Path) -> Option<Chunk<SmolStr>> {
darcs!("whatsnew", "-s")
.await
.filter(|s| !s.is_empty())
.map(|s| {
Chunk::info(merge_icons(
s.lines()
.map(|l| l.parse::<StatusIcon<Darcs>>().unwrap())
.collect::<SmallVec<[_; 8]>>(),
))
})
}
async fn worktree(&self, _opts: &Options, _path: &Path) -> Option<Chunk<SmolStr>> {
None
}
async fn stash(&self, _opts: &Options, _path: &Path) -> Option<Chunk<SmolStr>> {
None
}
async fn divergence(&self, _opts: &Options, _path: &Path) -> Option<Chunk<SmolStr>> {
None
}
}
impl FromStr for StatusIcon<Darcs> {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let chars = s.split_whitespace().next();
let icon = match chars {
Some("R") => StatusIcon::new("−"),
Some("A") => StatusIcon::new("✚"),
Some("M") => StatusIcon::new("●"),
Some("F") => StatusIcon::new("→"),
Some("T") => StatusIcon::new("→"),
_ => StatusIcon::new(""), };
Ok(icon)
}
}