+ use std::error::Error;
+ use std::fmt;
+ use std::path::Path;
+
+ use libpijul::pristine::sanakirja::Pristine;
+ use libpijul::TxnT;
+ use libpijul::TxnTExt;
+
+ pub struct Repository {
+ pristine: Pristine,
+ }
+
+ pub struct Change {
+ pub hash: String,
+ }
+
+ #[derive(Debug, Clone)]
+ pub struct NoSuchChannelError {
+ channel_name: String,
+ }
+
+ impl fmt::Display for NoSuchChannelError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "no such channel: {}", self.channel_name)
+ }
+ }
+
+ impl Error for NoSuchChannelError {}
+
+ impl Repository {
+ pub fn load(path: &str) -> Result<Repository, Box<dyn Error>> {
+ let repo_path = Path::new(path);
+ let pristine_path = repo_path.join(".pijul/pristine/db");
+ let pristine = Pristine::new(pristine_path)?;
+
+ return Ok(Repository {
+ pristine,
+ });
+ }
+
+ pub fn log(&mut self, channel_name: &str) -> Result<Vec<Change>, Box<dyn Error>> {
+ let txn = self.pristine.txn_begin()?;
+ let channel = txn.load_channel(&channel_name)?.ok_or(NoSuchChannelError {
+ channel_name: channel_name.to_string(),
+ })?;
+ let log = txn.log(&*channel.read(), 0)?;
+
+ let mut changes: Vec<Change> = Vec::new();
+ for pr in log {
+ let (_, (h, _)) = pr?;
+ changes.push(Change {
+ hash: format!("{:?}", h),
+ });
+ }
+
+ return Ok(changes);
+ }
+ }