pocket_cli/vcs/
timeline.rs1use std::path::Path;
6use std::fs;
7use serde::{Serialize, Deserialize};
8use anyhow::Result;
9use thiserror::Error;
10
11use crate::vcs::ShoveId;
12
13#[derive(Error, Debug)]
15pub enum TimelineError {
16 #[error("Timeline already exists: {0}")]
17 AlreadyExists(String),
18
19 #[error("Cannot delete the current timeline")]
20 CannotDeleteCurrent,
21
22 #[error("Timeline has no head shove")]
23 NoHead,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct RemoteTracking {
29 pub remote_name: String,
30 pub remote_timeline: String,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct Timeline {
36 pub name: String,
38
39 pub head: Option<ShoveId>,
41
42 pub remote: Option<RemoteTracking>,
44}
45
46impl Timeline {
47 pub fn new(name: &str, head: Option<ShoveId>) -> Self {
49 Self {
50 name: name.to_string(),
51 head,
52 remote: None,
53 }
54 }
55
56 pub fn load(path: &Path) -> Result<Self> {
58 let content = fs::read_to_string(path)?;
59 let timeline: Self = toml::from_str(&content)?;
60 Ok(timeline)
61 }
62
63 pub fn save(&self, path: &Path) -> Result<()> {
65 let content = toml::to_string_pretty(self)?;
66 fs::write(path, content)?;
67 Ok(())
68 }
69
70 pub fn update_head(&mut self, shove_id: ShoveId) {
72 self.head = Some(shove_id);
73 }
74
75 pub fn set_remote_tracking(&mut self, remote_name: &str, remote_timeline: &str) {
77 self.remote = Some(RemoteTracking {
78 remote_name: remote_name.to_string(),
79 remote_timeline: remote_timeline.to_string(),
80 });
81 }
82
83 }