#![warn(clippy::pedantic)] #![warn(clippy::nursery)] use std::collections::HashMap; use std::fs::{File, Metadata}; use std::path::{Path, PathBuf}; use std::time::Instant; mod workarea; struct ContributorId(String); struct ChannelId(String); struct PatchId(String); struct FileId(String); struct SpanId(String); struct Remote { url: String, name: String, } struct Contributor { id: ContributorId, emails: Vec, nickname: String, realname: Option, public_keys: Vec, } struct Channel { id: ChannelId, name: String, remotes: Vec, main_remote: Option, patches: Vec, } struct Patch { id: PatchId, authors: Vec, recorder: ContributorId, metadata: HashMap, added_spans: Vec, deleted_spans: Vec, added_files: Vec, deleted_files: Vec, } struct FileInfo { id: FileId, inode: Option, spans: Vec, added_by: Vec, renamed_by: Vec<(PatchId, PathBuf)>, deleted_by: Vec, } struct Span { id: SpanId, file: FileId, after: Vec, before: Vec, contents: Vec, added_by: Vec, deleted_by: Vec, } type DiffAlgorithm = fn(File, File) -> Diff; struct Diff(Vec); struct DiffSpan { left: Vec, right: Vec, } struct Log { entries: Vec, } enum LogEntry { CreatePatch(PatchId), } type RevertAlgorithm = fn(Patch) -> Patch; trait StagingArea { fn list_files() -> std::io::Result; fn open_file(path: &Path) -> std::io::Result; fn file_metadata(path: &Path) -> std::io::Result; fn is_file_changed(path: &Path, since: Instant) -> std::io::Result; } trait Repository { fn archive(&self) -> Vec; fn remotes(&self) -> Vec; fn main_remote(&self) -> Option; fn set_main_remote(&mut self, remote: Option); fn add_remote(&mut self, remote: Remote); fn delete_remote(&mut self, remote: Remote); fn push(&self, remote: Remote); fn pull(&mut self, remote: Remote); fn all_contributors(&self) -> Vec; fn contributor(&self, id: ContributorId) -> Contributor; fn credit(&self, filename: &Path, byte: usize) -> Option; fn all_channels(&self) -> Vec; fn active_channel(&self) -> ChannelId; fn channel(&self, id: ChannelId) -> Channel; fn create_channel(&mut self, channel: Channel); fn change_channel(&mut self, id: ChannelId) -> Channel; fn rename_channel(&mut self, id: ChannelId, name: &str) -> Channel; fn delete_channel(&mut self, id: ChannelId); fn add_patches_to_channel(&mut self, channel: ChannelId, patches: &[PatchId]) -> Channel; fn add_channel_to_channel(&mut self, channel: ChannelId, plus: ChannelId) -> Channel; fn all_patches(&self) -> Vec; fn active_patches(&self) -> Vec; fn patch(&self, id: PatchId) -> Option; fn create_patch(&mut self, patch: Patch); fn delete_patch(&mut self, id: PatchId); fn set_active_patches(&mut self, ids: &[PatchId]); fn combine_patches(&mut self, patches: &[PatchId]) -> Patch; fn active_files(&self) -> Vec; fn file(&self, id: FileId) -> Option; fn write_file_from_patch(&self, id: FileId, patch: PatchId) -> Vec; fn span(&self, id: SpanId) -> Option; }