summaryrefslogtreecommitdiff
path: root/src/lib.rs
blob: 7f6b86fedbc65ceca2488c0191a2c48547602a2c (plain)
#![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<String>,
	nickname: String,
	realname: Option<String>,
	public_keys: Vec<String>,
}

struct Channel {
	id: ChannelId,
	name: String,
	remotes: Vec<Remote>,
	main_remote: Option<Remote>,
	patches: Vec<PatchId>,
}

struct Patch {
	id: PatchId,
	authors: Vec<ContributorId>,
	recorder: ContributorId,
	metadata: HashMap<String, String>,
	added_spans: Vec<SpanId>,
	deleted_spans: Vec<SpanId>,
	added_files: Vec<FileId>,
	deleted_files: Vec<FileId>,
}

struct FileInfo {
	id: FileId,
	inode: Option<u64>,
	spans: Vec<SpanId>,
	added_by: Vec<PatchId>,
	renamed_by: Vec<(PatchId, PathBuf)>,
	deleted_by: Vec<PatchId>,
}

struct Span {
	id: SpanId,
	file: FileId,
	after: Vec<SpanId>,
	before: Vec<SpanId>,
	contents: Vec<u8>,
	added_by: Vec<PatchId>,
	deleted_by: Vec<PatchId>,
}

type DiffAlgorithm = fn(File, File) -> Diff;

struct Diff(Vec<DiffSpan>);

struct DiffSpan {
	left: Vec<u8>,
	right: Vec<u8>,
}

struct Log {
	entries: Vec<LogEntry>,
}

enum LogEntry {
	CreatePatch(PatchId),
}

type RevertAlgorithm = fn(Patch) -> Patch;

trait StagingArea {
	fn list_files() -> std::io::Result<Metadata>;
	fn open_file(path: &Path) -> std::io::Result<File>;
	fn file_metadata(path: &Path) -> std::io::Result<Metadata>;
	fn is_file_changed(path: &Path, since: Instant) -> std::io::Result<bool>;
}

trait Repository {
	fn archive(&self) -> Vec<u8>;

	fn remotes(&self) -> Vec<Remote>;
	fn main_remote(&self) -> Option<Remote>;
	fn set_main_remote(&mut self, remote: Option<Remote>);
	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<ContributorId>;
	fn contributor(&self, id: ContributorId) -> Contributor;
	fn credit(&self, filename: &Path, byte: usize) -> Option<ContributorId>;

	fn all_channels(&self) -> Vec<ChannelId>;
	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<PatchId>;
	fn active_patches(&self) -> Vec<PatchId>;
	fn patch(&self, id: PatchId) -> Option<Patch>;
	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<FileId>;
	fn file(&self, id: FileId) -> Option<FileInfo>;
	fn write_file_from_patch(&self, id: FileId, patch: PatchId) -> Vec<u8>;

	fn span(&self, id: SpanId) -> Option<Span>;
}