loro_internal/
configure.rs1pub use crate::container::richtext::config::{StyleConfig, StyleConfigMap};
2use crate::LoroDoc;
3
4#[derive(Clone, Debug)]
5pub struct Configure {
6 pub(crate) text_style_config: Arc<RwLock<StyleConfigMap>>,
7 record_timestamp: Arc<AtomicBool>,
8 pub(crate) merge_interval_in_s: Arc<AtomicI64>,
9 pub(crate) editable_detached_mode: Arc<AtomicBool>,
10}
11
12impl LoroDoc {
13 pub(crate) fn set_config(&self, config: &Configure) {
14 self.config_text_style(config.text_style_config.read().unwrap().clone());
15 self.set_record_timestamp(config.record_timestamp());
16 self.set_change_merge_interval(config.merge_interval());
17 self.set_detached_editing(config.detached_editing());
18 }
19}
20
21impl Default for Configure {
22 fn default() -> Self {
23 Self {
24 text_style_config: Arc::new(RwLock::new(StyleConfigMap::default_rich_text_config())),
25 record_timestamp: Arc::new(AtomicBool::new(false)),
26 editable_detached_mode: Arc::new(AtomicBool::new(false)),
27 merge_interval_in_s: Arc::new(AtomicI64::new(1000)),
28 }
29 }
30}
31
32impl Configure {
33 pub fn fork(&self) -> Self {
34 Self {
35 text_style_config: Arc::new(RwLock::new(
36 self.text_style_config.read().unwrap().clone(),
37 )),
38 record_timestamp: Arc::new(AtomicBool::new(
39 self.record_timestamp
40 .load(std::sync::atomic::Ordering::Relaxed),
41 )),
42 merge_interval_in_s: Arc::new(AtomicI64::new(
43 self.merge_interval_in_s
44 .load(std::sync::atomic::Ordering::Relaxed),
45 )),
46 editable_detached_mode: Arc::new(AtomicBool::new(
47 self.editable_detached_mode
48 .load(std::sync::atomic::Ordering::Relaxed),
49 )),
50 }
51 }
52
53 pub fn text_style_config(&self) -> &Arc<RwLock<StyleConfigMap>> {
54 &self.text_style_config
55 }
56
57 pub fn record_timestamp(&self) -> bool {
58 self.record_timestamp
59 .load(std::sync::atomic::Ordering::Relaxed)
60 }
61
62 pub fn set_record_timestamp(&self, record: bool) {
63 self.record_timestamp
64 .store(record, std::sync::atomic::Ordering::Relaxed);
65 }
66
67 pub fn detached_editing(&self) -> bool {
68 self.editable_detached_mode
69 .load(std::sync::atomic::Ordering::Relaxed)
70 }
71
72 pub fn set_detached_editing(&self, mode: bool) {
73 self.editable_detached_mode
74 .store(mode, std::sync::atomic::Ordering::Relaxed);
75 }
76
77 pub fn merge_interval(&self) -> i64 {
78 self.merge_interval_in_s
79 .load(std::sync::atomic::Ordering::Relaxed)
80 }
81
82 pub fn set_merge_interval(&self, interval: i64) {
83 self.merge_interval_in_s
84 .store(interval, std::sync::atomic::Ordering::Relaxed);
85 }
86}
87
88#[derive(Debug)]
89pub struct DefaultRandom;
90
91#[cfg(test)]
92use std::sync::atomic::AtomicU64;
93use std::sync::{
94 atomic::{AtomicBool, AtomicI64},
95 Arc, RwLock,
96};
97#[cfg(test)]
98static mut TEST_RANDOM: AtomicU64 = AtomicU64::new(0);
99
100impl SecureRandomGenerator for DefaultRandom {
101 fn fill_byte(&self, dest: &mut [u8]) {
102 #[cfg(not(test))]
103 getrandom::getrandom(dest).unwrap();
104
105 #[cfg(test)]
106 unsafe {
108 #[allow(static_mut_refs)]
109 let bytes = TEST_RANDOM.fetch_add(1, std::sync::atomic::Ordering::Release);
110 dest.copy_from_slice(&bytes.to_le_bytes());
111 }
112 }
113}
114
115pub trait SecureRandomGenerator: Send + Sync {
116 fn fill_byte(&self, dest: &mut [u8]);
117 fn next_u64(&self) -> u64 {
118 let mut buf = [0u8; 8];
119 self.fill_byte(&mut buf);
120 u64::from_le_bytes(buf)
121 }
122
123 fn next_u32(&self) -> u32 {
124 let mut buf = [0u8; 4];
125 self.fill_byte(&mut buf);
126 u32::from_le_bytes(buf)
127 }
128
129 fn next_i64(&self) -> i64 {
130 let mut buf = [0u8; 8];
131 self.fill_byte(&mut buf);
132 i64::from_le_bytes(buf)
133 }
134
135 fn next_i32(&self) -> i32 {
136 let mut buf = [0u8; 4];
137 self.fill_byte(&mut buf);
138 i32::from_le_bytes(buf)
139 }
140}