Add values_at

This commit is contained in:
Andrew Jeffery 2022-04-01 10:37:40 +01:00
parent 89eb598858
commit bcf191bea3
3 changed files with 40 additions and 1 deletions

View file

@ -12,7 +12,7 @@ use crate::types::{
ActorId, AssignPatch, ChangeHash, Clock, ElemId, Export, Exportable, Key, ObjId, Op, OpId,
OpType, Patch, ScalarValue, Value,
};
use crate::{legacy, query, types, ObjType, RangeAt};
use crate::{legacy, query, types, ObjType, RangeAt, ValuesAt};
use crate::{AutomergeError, Change, Prop};
use crate::{KeysAt, Values};
use serde::Serialize;
@ -397,6 +397,17 @@ impl Automerge {
}
}
/// Historical version of [`values`](Self::values).
pub fn values_at<O: AsRef<ExId>>(&self, obj: O, heads: &[ChangeHash]) -> ValuesAt {
if let Ok(obj) = self.exid_to_obj(obj.as_ref()) {
let clock = self.clock_at(heads);
let iter_range = self.ops.range_at(obj, .., clock);
ValuesAt::new(self, iter_range)
} else {
ValuesAt::new(self, None)
}
}
/// Get the length of the given object.
pub fn length<O: AsRef<ExId>>(&self, obj: O) -> usize {
if let Ok(inner_obj) = self.exid_to_obj(obj.as_ref()) {

View file

@ -47,6 +47,7 @@ pub mod transaction;
mod types;
mod value;
mod values;
mod values_at;
#[cfg(feature = "optree-visualisation")]
mod visualisation;
@ -66,5 +67,6 @@ pub use range_at::RangeAt;
pub use types::{ActorId, AssignPatch, ChangeHash, ObjType, OpType, Patch, Prop};
pub use value::{ScalarValue, Value};
pub use values::Values;
pub use values_at::ValuesAt;
pub const ROOT: ObjId = ObjId::Root;

View file

@ -0,0 +1,26 @@
use crate::{exid::ExId, Value};
use std::ops::RangeFull;
use crate::{query, Automerge};
pub struct ValuesAt<'a, 'k> {
range: Option<query::RangeAt<'k, RangeFull>>,
doc: &'a Automerge,
}
impl<'a, 'k> ValuesAt<'a, 'k> {
pub(crate) fn new(doc: &'a Automerge, range: Option<query::RangeAt<'k, RangeFull>>) -> Self {
Self { range, doc }
}
}
impl<'a, 'k> Iterator for ValuesAt<'a, 'k> {
type Item = (String, Value, ExId);
fn next(&mut self) -> Option<Self::Item> {
self.range
.as_mut()?
.next()
.map(|(key, value, id)| (self.doc.to_string(key), value, self.doc.id_to_exid(id)))
}
}