use radicle::cob::stream::{CobRange, CobStream, Stream};
use radicle::cob::{ObjectId, Op, TypeName};
use radicle::git::Oid;
use snafu::ResultExt;
use crate::models::activity_feed::ActivityFeedOperation;
pub struct CobStreamProcessor<'a> {
git2_repo: &'a radicle::git::raw::Repository,
typename: &'a TypeName,
id: &'a ObjectId,
}
impl<'a> CobStreamProcessor<'a> {
pub fn new(
git2_repo: &'a radicle::git::raw::Repository,
typename: &'a TypeName,
id: &'a ObjectId,
) -> Self {
Self {
git2_repo,
typename,
id,
}
}
pub fn fetch_entries_since<A>(
&self,
since_oid: Option<Oid>,
) -> Result<Vec<Op<A>>, snafu::Whatever>
where
A: serde::Serialize + for<'de> serde::Deserialize<'de> + Clone,
{
let stream = Stream::<A>::new(
self.git2_repo,
CobRange::new(self.typename, self.id),
self.typename.clone(),
);
let entries = if let Some(since_oid) = since_oid {
tracing::debug!("{} Last processed operation ID: {:?}", self.id, since_oid);
stream
.since(since_oid)
.whatever_context("Unable to create since cob stream")?
.filter_map(|s| s.ok())
.filter(|entry| entry.id() != since_oid.into())
.collect()
} else {
tracing::debug!(
"{} No previous operations found (first time processing)",
self.id
);
stream
.all()
.whatever_context("Unable to create all cob stream")?
.filter_map(|s| s.ok())
.collect()
};
Ok(entries)
}
}
pub struct CobStateAccumulator {
title: String,
state: String,
}
impl CobStateAccumulator {
pub fn new() -> Self {
Self {
title: String::new(),
state: String::from("open"),
}
}
pub fn title(&self) -> String {
self.title.clone()
}
pub fn state(&self) -> String {
self.state.clone()
}
pub fn update_from_action(&mut self, action_json: &serde_json::Value) {
if let Some(state) = action_json
.get("state")
.and_then(|t| t.get("status"))
.and_then(|s| s.as_str())
{
self.state = state.to_string();
}
if let Some(title) = action_json.get("title").and_then(|t| t.as_str()) {
self.title = title.to_string();
}
}
}
impl From<ActivityFeedOperation> for CobStateAccumulator {
fn from(value: ActivityFeedOperation) -> Self {
Self {
title: value.title().to_string(),
state: value.status().to_string(),
}
}
}