1use onestore::{
2 Arena, CommitError, CommitState, ExGuid, Section, Transaction,
3 op::{Edit, Op, PageOp},
4};
5use std::{
6 io,
7 ops::Range,
8 time::{SystemTime, UNIX_EPOCH},
9};
10
11/// The transaction replacing `range` of `text` in `image`, typed now.
12pub fn replaced(
13 image: &[u8],
14 space: ExGuid,
15 text: ExGuid,
16 range: Range<u32>,
17 with: &str,
18) -> Result<Transaction, CommitError> {
19 let failed = |error: String| CommitError {
20 state: CommitState::NotCommitted,
21 error: io::Error::new(io::ErrorKind::InvalidData, error),
22 };
23 let arena = Arena::default();
24 let mut section = Section::open(&arena, image.to_vec()).map_err(|e| failed(e.to_string()))?;
25 let at = SystemTime::now()
26 .duration_since(UNIX_EPOCH)
27 .map_err(|e| failed(e.to_string()))?
28 .as_nanos() as u64
29 / 100
30 + 116_444_736_000_000_000;
31 let edit = Edit {
32 at,
33 ops: vec![Op::Page {
34 space,
35 op: PageOp::Text {
36 text,
37 range,
38 with: with.to_owned(),
39 },
40 }],
41 };
42 section
43 .apply("Concurrent client", &edit)
44 .map_err(|e| failed(format!("{e:?}")))?;
45 section
46 .seal()
47 .map_err(|e| failed(e.to_string()))?
48 .ok_or_else(|| failed("The edit changed nothing".into()))
49}