Skip to main content

readmer/
workspace.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{AncestorPath, Config, Git, RootedPath, Utf8Path, Utf8PathBuf};
4use alloc::string::String;
5use core::str::FromStr;
6use dogma::FromPathError;
7use std::{
8    io::{Error, ErrorKind, Result},
9    path::PathBuf,
10};
11
12#[derive(Clone, Debug, Default)]
13pub struct Workspace(pub(crate) RootedPath);
14
15impl FromStr for Workspace {
16    type Err = Error;
17
18    fn from_str(input: &str) -> core::result::Result<Self, Self::Err> {
19        let path = RootedPath::from_str(input)?;
20        if let Some(up) = &path.up
21            && !up.is_dir()
22        {
23            return Err(Error::from(ErrorKind::NotADirectory));
24        }
25        Ok(Self(path))
26    }
27}
28
29impl AsRef<RootedPath> for Workspace {
30    fn as_ref(&self) -> &RootedPath {
31        &self.0
32    }
33}
34
35impl Workspace {
36    pub fn locate() -> Result<Self> {
37        let git = Git::default();
38        let down = git.rev_parse_show_prefix().unwrap(); // FIXME
39        let up_count = down.components().count();
40        if up_count == 0 {
41            return Ok(Self::default());
42        }
43        let up = AncestorPath::try_from(up_count).ok();
44        Ok(Self(RootedPath { up, down }))
45    }
46
47    pub fn path(&self) -> &RootedPath {
48        &self.0
49    }
50
51    pub fn config(&self) -> Config {
52        Config(self.config_path())
53    }
54
55    pub fn config_path(&self) -> Utf8PathBuf {
56        self.join(".config/readmer")
57    }
58
59    pub fn join(&self, path: impl AsRef<Utf8Path>) -> Utf8PathBuf {
60        self.0.join(path)
61    }
62}