use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::api::ids::{CustomViewId, CycleId, FavoriteId, IssueId, ProjectId, TeamId};
mod files;
#[cfg(test)]
mod tests;
mod time;
pub use files::*;
pub use time::*;
pub const VERSION: u32 = 1;
pub const MAX_ROWS: usize = 100;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ViewSnapshot {
pub version: u32,
pub workspace: PathBuf,
pub cwd: PathBuf,
pub pid: u32,
pub updated_at: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub closed_at: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub herdr_pane: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub team: Option<TeamRef>,
pub destination: Destination,
pub screen: Screen,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub project: Option<NamedRef<ProjectId>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cycle: Option<NamedRef<CycleId>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub issue: Option<IssueRef>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub search: Option<String>,
pub group_by: GroupBy,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub lists: Vec<ListSettings>,
#[serde(default)]
pub rows: Vec<Row>,
#[serde(default)]
pub rows_total: usize,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub selected_row: Option<usize>,
}
impl ViewSnapshot {
pub fn same_view(&self, other: &Self) -> bool {
let mut other = other.clone();
other.updated_at.clone_from(&self.updated_at);
other.closed_at.clone_from(&self.closed_at);
*self == other
}
pub fn selected(&self) -> Option<&Row> {
self.rows.get(self.selected_row?)
}
}
#[derive(Debug, Clone)]
pub struct Origin {
pub workspace: PathBuf,
pub cwd: PathBuf,
pub pid: u32,
pub herdr_pane: Option<String>,
}
impl Origin {
pub fn current(cwd: PathBuf) -> Self {
Self {
workspace: workspace_of(&cwd),
cwd,
pid: std::process::id(),
herdr_pane: std::env::var("HERDR_PANE_ID")
.ok()
.filter(|p| !p.is_empty()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TeamRef {
pub id: TeamId,
pub key: String,
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NamedRef<I> {
pub id: I,
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IssueRef {
pub id: IssueId,
pub identifier: String,
pub title: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum Destination {
MyIssues,
Views,
View {
id: CustomViewId,
name: String,
},
Team {
team: TeamRef,
section: Section,
},
Favorite {
id: FavoriteId,
title: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Section {
Issues,
Cycles,
Projects,
Views,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Screen {
IssueList,
IssueDetail,
ProjectList,
ProjectDetail,
CycleList,
CycleDetail,
ViewList,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GroupBy {
Status,
Assignee,
Priority,
Project,
None,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Source {
Team,
My,
View,
Project,
Cycle,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Preset {
Active,
Backlog,
All,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ListSettings {
pub source: Source,
pub preset: Preset,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub priority: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub selected: Option<IssueRef>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RowKind {
Issue,
Project,
Cycle,
View,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Row {
pub kind: RowKind,
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub identifier: Option<String>,
pub title: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub assignee: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub priority: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
}