1use std::collections::{Bound, HashMap};
2use std::ffi::{c_char, c_void, CStr, CString};
3use std::mem::{forget, ManuallyDrop, MaybeUninit};
4use std::ops::{Deref, RangeBounds};
5use std::ptr::{null, null_mut};
6use std::sync::atomic::{AtomicPtr, Ordering};
7use std::sync::Arc;
8use yrs::block::{ClientID, EmbedPrelim, ItemContent, Prelim, Unused};
9use yrs::branch::BranchPtr;
10use yrs::encoding::read::Error;
11use yrs::error::UpdateError;
12use yrs::json_path::JsonPathIter as NativeJsonPathIter;
13use yrs::types::array::ArrayEvent;
14use yrs::types::array::ArrayIter as NativeArrayIter;
15use yrs::types::map::MapEvent;
16use yrs::types::map::MapIter as NativeMapIter;
17use yrs::types::text::{Diff, TextEvent, YChange};
18use yrs::types::weak::{LinkSource, Unquote as NativeUnquote, WeakEvent, WeakRef};
19use yrs::types::xml::{Attributes as NativeAttributes, XmlOut};
20use yrs::types::xml::{TreeWalker as NativeTreeWalker, XmlFragment};
21use yrs::types::xml::{XmlEvent, XmlTextEvent};
22use yrs::types::{Attrs, Change, Delta, EntryChange, Event, PathSegment, ToJson, TypeRef};
23use yrs::undo::EventKind;
24use yrs::updates::decoder::{Decode, DecoderV1};
25use yrs::updates::encoder::{Encode, Encoder, EncoderV1, EncoderV2};
26use yrs::{
27 uuid_v4, Any, Array, ArrayRef, Assoc, BranchID, GetString, IdSet, JsonPath, JsonPathEval, Map,
28 MapRef, Number, Observable, OffsetKind, Options, Origin, Out, Quotable, ReadTxn, Snapshot,
29 StateVector, StickyIndex, Store, SubdocsEvent, SubdocsEventIter, Text, TextRef, Transact,
30 TransactionCleanupEvent, Update, Xml, XmlElementPrelim, XmlElementRef, XmlFragmentRef,
31 XmlTextPrelim, XmlTextRef, ID,
32};
33
34pub const Y_JSON: i8 = -9;
37
38pub const Y_JSON_BOOL: i8 = -8;
40
41pub const Y_JSON_NUM: i8 = -7;
43
44pub const Y_JSON_INT: i8 = -6;
46
47pub const Y_JSON_STR: i8 = -5;
49
50pub const Y_JSON_BUF: i8 = -4;
52
53pub const Y_JSON_ARR: i8 = -3;
56
57pub const Y_JSON_MAP: i8 = -2;
60
61pub const Y_JSON_NULL: i8 = -1;
63
64pub const Y_JSON_UNDEF: i8 = 0;
66
67pub const Y_ARRAY: i8 = 1;
69
70pub const Y_MAP: i8 = 2;
72
73pub const Y_TEXT: i8 = 3;
75
76pub const Y_XML_ELEM: i8 = 4;
78
79pub const Y_XML_TEXT: i8 = 5;
81
82pub const Y_XML_FRAG: i8 = 6;
84
85pub const Y_DOC: i8 = 7;
87
88pub const Y_WEAK_LINK: i8 = 8;
90
91pub const Y_UNDEFINED: i8 = 9;
94
95pub const Y_TRUE: u8 = 1;
97
98pub const Y_FALSE: u8 = 0;
100
101pub type Doc = yrs::Doc;
111
112pub type Branch = yrs::branch::Branch;
120
121#[repr(transparent)]
123pub struct ArrayIter(NativeArrayIter<&'static Transaction, Transaction>);
124
125#[repr(transparent)]
127pub struct WeakIter(NativeUnquote<'static, Transaction>);
128
129#[repr(transparent)]
132pub struct MapIter(NativeMapIter<'static, &'static Transaction, Transaction>);
133
134#[repr(transparent)]
138pub struct Attributes(NativeAttributes<'static, &'static Transaction, Transaction>);
139
140#[repr(transparent)]
145pub struct TreeWalker(NativeTreeWalker<'static, &'static Transaction, Transaction>);
146
147#[repr(transparent)]
151pub struct Transaction(TransactionInner);
152
153#[repr(C)]
155pub struct JsonPathIter {
156 query: String,
157 json_path: Box<JsonPath<'static>>,
158 inner: NativeJsonPathIter<'static, Transaction>,
159}
160
161enum TransactionInner {
162 ReadOnly(yrs::Transaction<'static>),
163 ReadWrite(yrs::TransactionMut<'static>),
164}
165
166impl Transaction {
167 fn read_only(txn: yrs::Transaction) -> Self {
168 Transaction(TransactionInner::ReadOnly(unsafe {
169 std::mem::transmute(txn)
170 }))
171 }
172
173 fn read_write(txn: yrs::TransactionMut) -> Self {
174 Transaction(TransactionInner::ReadWrite(unsafe {
175 std::mem::transmute(txn)
176 }))
177 }
178
179 fn is_writeable(&self) -> bool {
180 match &self.0 {
181 TransactionInner::ReadOnly(_) => false,
182 TransactionInner::ReadWrite(_) => true,
183 }
184 }
185
186 fn as_mut(&mut self) -> Option<&mut yrs::TransactionMut<'static>> {
187 match &mut self.0 {
188 TransactionInner::ReadOnly(_) => None,
189 TransactionInner::ReadWrite(txn) => Some(txn),
190 }
191 }
192}
193
194impl ReadTxn for Transaction {
195 fn store(&self) -> &Store {
196 match &self.0 {
197 TransactionInner::ReadOnly(txn) => txn.store(),
198 TransactionInner::ReadWrite(txn) => txn.store(),
199 }
200 }
201}
202
203#[repr(C)]
206pub struct YMapEntry {
207 pub key: *const c_char,
209 pub value: *const YOutput,
212}
213
214impl YMapEntry {
215 fn new(key: &str, value: Box<YOutput>) -> Self {
216 let key = CString::new(key).unwrap().into_raw();
217 let value = Box::into_raw(value) as *const YOutput;
218 YMapEntry { key, value }
219 }
220}
221
222impl Drop for YMapEntry {
223 fn drop(&mut self) {
224 unsafe {
225 drop(CString::from_raw(self.key as *mut c_char));
226 drop(Box::from_raw(self.value as *mut YOutput));
227 }
228 }
229}
230
231#[repr(C)]
234pub struct YXmlAttr {
235 pub name: *const c_char,
236 pub value: *const YOutput,
237}
238
239impl Drop for YXmlAttr {
240 fn drop(&mut self) {
241 unsafe {
242 drop(CString::from_raw(self.name as *mut _));
243 if (!self.value.is_null()) {
244 drop(Box::from_raw(self.value as *mut YOutput));
245 }
246 }
247 }
248}
249
250#[repr(C)]
252pub struct YOptions {
253 pub id: u64,
260
261 pub guid: *const c_char,
264
265 pub collection_id: *const c_char,
268
269 pub flags: u8,
277}
278
279pub const Y_OFFSET_BYTES: u8 = 0;
282
283pub const Y_OFFSET_UTF16: u8 = 1;
286
287pub const Y_SKIP_GC: u8 = 1 << 1;
290
291pub const Y_AUTO_LOAD: u8 = 1 << 2;
294
295pub const Y_SHOULD_LOAD: u8 = 1 << 3;
297
298pub const Y_CLEANUP_FMT: u8 = 1 << 4;
304
305impl Into<Options> for YOptions {
306 fn into(self) -> Options {
307 let mut offset_kind = OffsetKind::Bytes;
308 if self.flags & Y_OFFSET_UTF16 != 0 {
309 offset_kind = OffsetKind::Utf16;
310 }
311 let skip_gc = self.flags & Y_SKIP_GC != 0;
312 let auto_load = self.flags & Y_AUTO_LOAD != 0;
313 let should_load = self.flags & Y_SHOULD_LOAD != 0;
314 let cleanup_formatting = self.flags & Y_CLEANUP_FMT != 0;
315 let guid = if self.guid.is_null() {
316 uuid_v4()
317 } else {
318 let c_str = unsafe { CStr::from_ptr(self.guid) };
319 let str = c_str.to_str().unwrap();
320 str.into()
321 };
322 let collection_id = if self.collection_id.is_null() {
323 None
324 } else {
325 let c_str = unsafe { CStr::from_ptr(self.collection_id) };
326 let str = Arc::from(c_str.to_str().unwrap());
327 Some(str)
328 };
329 Options {
330 client_id: ClientID::new(self.id),
331 guid,
332 collection_id,
333 skip_gc,
334 auto_load,
335 should_load,
336 offset_kind,
337 cleanup_formatting,
338 }
339 }
340}
341
342impl From<Options> for YOptions {
343 fn from(o: Options) -> Self {
344 let mut flags = 0;
345 if o.offset_kind == OffsetKind::Utf16 {
346 flags |= Y_OFFSET_UTF16;
347 }
348 if o.skip_gc {
349 flags |= Y_SKIP_GC;
350 }
351 if o.auto_load {
352 flags |= Y_AUTO_LOAD;
353 }
354 if o.should_load {
355 flags |= Y_SHOULD_LOAD;
356 }
357 if o.cleanup_formatting {
358 flags |= Y_CLEANUP_FMT;
359 }
360
361 YOptions {
362 id: o.client_id.get(),
363 guid: CString::new(o.guid.as_ref()).unwrap().into_raw(),
364 collection_id: if let Some(collection_id) = o.collection_id {
365 CString::new(collection_id.to_string()).unwrap().into_raw()
366 } else {
367 null_mut()
368 },
369 flags,
370 }
371 }
372}
373
374#[no_mangle]
376pub unsafe extern "C" fn yoptions() -> YOptions {
377 Options::default().into()
378}
379
380#[no_mangle]
382pub unsafe extern "C" fn ydoc_destroy(value: *mut Doc) {
383 if !value.is_null() {
384 drop(Box::from_raw(value));
385 }
386}
387
388#[no_mangle]
390pub unsafe extern "C" fn ymap_entry_destroy(value: *mut YMapEntry) {
391 if !value.is_null() {
392 drop(Box::from_raw(value));
393 }
394}
395
396#[no_mangle]
398pub unsafe extern "C" fn yxmlattr_destroy(attr: *mut YXmlAttr) {
399 if !attr.is_null() {
400 drop(Box::from_raw(attr));
401 }
402}
403
404#[no_mangle]
407pub unsafe extern "C" fn ystring_destroy(str: *mut c_char) {
408 if !str.is_null() {
409 drop(CString::from_raw(str));
410 }
411}
412
413#[no_mangle]
418pub unsafe extern "C" fn ybinary_destroy(ptr: *mut c_char, len: u32) {
419 if !ptr.is_null() {
420 drop(Vec::from_raw_parts(ptr, len as usize, len as usize));
421 }
422}
423
424#[no_mangle]
428pub extern "C" fn ydoc_new() -> *mut Doc {
429 Box::into_raw(Box::new(Doc::new()))
430}
431
432#[no_mangle]
438pub unsafe extern "C" fn ydoc_clone(doc: *mut Doc) -> *mut Doc {
439 let doc = doc.as_mut().unwrap();
440 Box::into_raw(Box::new(doc.clone()))
441}
442
443#[no_mangle]
447pub extern "C" fn ydoc_new_with_options(options: YOptions) -> *mut Doc {
448 Box::into_raw(Box::new(Doc::with_options(options.into())))
449}
450
451#[no_mangle]
453pub unsafe extern "C" fn ydoc_id(doc: *mut Doc) -> u64 {
454 let doc = doc.as_ref().unwrap();
455 doc.client_id().get()
456}
457
458#[no_mangle]
462pub unsafe extern "C" fn ydoc_guid(doc: *mut Doc) -> *mut c_char {
463 let doc = doc.as_ref().unwrap();
464 let uid = doc.guid();
465 CString::new(uid.as_ref()).unwrap().into_raw()
466}
467
468#[no_mangle]
473pub unsafe extern "C" fn ydoc_collection_id(doc: *mut Doc) -> *mut c_char {
474 let doc = doc.as_ref().unwrap();
475 if let Some(cid) = doc.collection_id() {
476 CString::new(cid.as_ref()).unwrap().into_raw()
477 } else {
478 null_mut()
479 }
480}
481
482#[no_mangle]
485pub unsafe extern "C" fn ydoc_should_load(doc: *mut Doc) -> u8 {
486 let doc = doc.as_ref().unwrap();
487 doc.should_load() as u8
488}
489
490#[no_mangle]
493pub unsafe extern "C" fn ydoc_auto_load(doc: *mut Doc) -> u8 {
494 let doc = doc.as_ref().unwrap();
495 doc.auto_load() as u8
496}
497
498#[repr(transparent)]
499struct CallbackState(*mut c_void);
500
501unsafe impl Send for CallbackState {}
502unsafe impl Sync for CallbackState {}
503
504impl CallbackState {
505 #[inline]
506 fn new(state: *mut c_void) -> Self {
507 CallbackState(state)
508 }
509}
510
511unsafe fn origin(len: u32, ptr: *const c_char) -> Origin {
513 let bytes: &[u8] = if len == 0 {
514 &[]
515 } else {
516 std::slice::from_raw_parts(ptr as *const u8, len as usize)
517 };
518 Origin::from(bytes)
519}
520
521unsafe fn txn_mut<'a>(txn: *mut Transaction) -> &'a mut yrs::TransactionMut<'static> {
523 txn.as_mut()
524 .unwrap()
525 .as_mut()
526 .expect("read-write transaction expected")
527}
528
529#[no_mangle]
532pub unsafe extern "C" fn ytransaction_observe_updates_v1(
533 txn: *mut Transaction,
534 key_len: u32,
535 key: *const c_char,
536 state: *mut c_void,
537 cb: extern "C" fn(*mut c_void, u32, *const c_char),
538) {
539 let state = CallbackState::new(state);
540 let key = origin(key_len, key);
541 txn_mut(txn).observe_update_v1(key, move |_, e| {
542 let bytes = &e.update;
543 let len = bytes.len() as u32;
544 cb(state.0, len, bytes.as_ptr() as *const c_char)
545 });
546}
547
548#[no_mangle]
551pub unsafe extern "C" fn ytransaction_unobserve_updates_v1(
552 txn: *mut Transaction,
553 key_len: u32,
554 key: *const c_char,
555) -> u8 {
556 let key = origin(key_len, key);
557 txn_mut(txn).unobserve_update_v1(key) as u8
558}
559
560#[no_mangle]
563pub unsafe extern "C" fn ytransaction_observe_updates_v2(
564 txn: *mut Transaction,
565 key_len: u32,
566 key: *const c_char,
567 state: *mut c_void,
568 cb: extern "C" fn(*mut c_void, u32, *const c_char),
569) {
570 let state = CallbackState::new(state);
571 let key = origin(key_len, key);
572 txn_mut(txn).observe_update_v2(key, move |_, e| {
573 let bytes = &e.update;
574 let len = bytes.len() as u32;
575 cb(state.0, len, bytes.as_ptr() as *const c_char)
576 });
577}
578
579#[no_mangle]
582pub unsafe extern "C" fn ytransaction_unobserve_updates_v2(
583 txn: *mut Transaction,
584 key_len: u32,
585 key: *const c_char,
586) -> u8 {
587 let key = origin(key_len, key);
588 txn_mut(txn).unobserve_update_v2(key) as u8
589}
590
591#[no_mangle]
594pub unsafe extern "C" fn ytransaction_observe_after_transaction(
595 txn: *mut Transaction,
596 key_len: u32,
597 key: *const c_char,
598 state: *mut c_void,
599 cb: extern "C" fn(*mut c_void, *mut YAfterTransactionEvent),
600) {
601 let state = CallbackState::new(state);
602 let key = origin(key_len, key);
603 txn_mut(txn).observe_transaction_cleanup(key, move |_, e| {
604 let mut event = YAfterTransactionEvent::new(e);
605 cb(state.0, (&mut event) as *mut _);
606 });
607}
608
609#[no_mangle]
612pub unsafe extern "C" fn ytransaction_unobserve_after_transaction(
613 txn: *mut Transaction,
614 key_len: u32,
615 key: *const c_char,
616) -> u8 {
617 let key = origin(key_len, key);
618 txn_mut(txn).unobserve_transaction_cleanup(key) as u8
619}
620
621#[no_mangle]
624pub unsafe extern "C" fn ytransaction_observe_subdocs(
625 txn: *mut Transaction,
626 key_len: u32,
627 key: *const c_char,
628 state: *mut c_void,
629 cb: extern "C" fn(*mut c_void, *mut YSubdocsEvent),
630) {
631 let state = CallbackState::new(state);
632 let key = origin(key_len, key);
633 txn_mut(txn).observe_subdocs(key, move |_, e| {
634 let mut event = YSubdocsEvent::new(e);
635 cb(state.0, (&mut event) as *mut _);
636 });
637}
638
639#[no_mangle]
642pub unsafe extern "C" fn ytransaction_unobserve_subdocs(
643 txn: *mut Transaction,
644 key_len: u32,
645 key: *const c_char,
646) -> u8 {
647 let key = origin(key_len, key);
648 txn_mut(txn).unobserve_subdocs(key) as u8
649}
650
651#[no_mangle]
654pub unsafe extern "C" fn ytransaction_observe_clear(
655 txn: *mut Transaction,
656 key_len: u32,
657 key: *const c_char,
658 state: *mut c_void,
659 cb: extern "C" fn(*mut c_void, *mut Doc),
660) {
661 let state = CallbackState::new(state);
662 let key = origin(key_len, key);
663 txn_mut(txn).observe_destroy(key, move |_, e| cb(state.0, e as *const Doc as *mut _));
664}
665
666#[no_mangle]
669pub unsafe extern "C" fn ytransaction_unobserve_clear(
670 txn: *mut Transaction,
671 key_len: u32,
672 key: *const c_char,
673) -> u8 {
674 let key = origin(key_len, key);
675 txn_mut(txn).unobserve_destroy(key) as u8
676}
677
678#[no_mangle]
680pub unsafe extern "C" fn ydoc_load(doc: *mut Doc, parent_txn: *mut Transaction) {
681 let doc = doc.as_ref().unwrap();
682 let txn = parent_txn.as_mut().unwrap();
683 if let Some(txn) = txn.as_mut() {
684 doc.load(txn)
685 } else {
686 panic!("ydoc_load: passed read-only parent transaction, where read-write one was expected")
687 }
688}
689
690#[no_mangle]
693pub unsafe extern "C" fn ydoc_clear(doc: *mut Doc, parent_txn: *mut Transaction) {
694 let doc = doc.as_mut().unwrap();
695 let txn = parent_txn.as_mut();
696 let txn = txn.and_then(|tx| tx.as_mut());
697 doc.destroy(txn);
698}
699
700#[no_mangle]
707pub unsafe extern "C" fn ydoc_read_transaction(doc: *mut Doc) -> *mut Transaction {
708 assert!(!doc.is_null());
709
710 let doc = doc.as_mut().unwrap();
711 if let Ok(txn) = doc.try_transact() {
712 Box::into_raw(Box::new(Transaction::read_only(txn)))
713 } else {
714 null_mut()
715 }
716}
717
718#[no_mangle]
730pub unsafe extern "C" fn ydoc_write_transaction(
731 doc: *mut Doc,
732 origin_len: u32,
733 origin: *const c_char,
734) -> *mut Transaction {
735 assert!(!doc.is_null());
736
737 let doc = doc.as_mut().unwrap();
738 if origin_len == 0 {
739 if let Ok(txn) = doc.try_transact_mut() {
740 Box::into_raw(Box::new(Transaction::read_write(txn)))
741 } else {
742 null_mut()
743 }
744 } else {
745 let origin = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
746 if let Ok(txn) = doc.try_transact_mut_with(origin) {
747 Box::into_raw(Box::new(Transaction::read_write(txn)))
748 } else {
749 null_mut()
750 }
751 }
752}
753
754#[no_mangle]
756pub unsafe extern "C" fn ytransaction_subdocs(
757 txn: *mut Transaction,
758 len: *mut u32,
759) -> *mut *mut Doc {
760 let txn = txn.as_ref().unwrap();
761 let subdocs: Vec<_> = txn
762 .subdocs()
763 .map(|doc| doc as *const Doc as *mut Doc)
764 .collect();
765 let out = subdocs.into_boxed_slice();
766 *len = out.len() as u32;
767 Box::into_raw(out) as *mut _
768}
769
770#[no_mangle]
774pub unsafe extern "C" fn ytransaction_commit(txn: *mut Transaction) {
775 assert!(!txn.is_null());
776 drop(Box::from_raw(txn)); }
778
779#[no_mangle]
783pub unsafe extern "C" fn ytransaction_force_gc(txn: *mut Transaction) {
784 assert!(!txn.is_null());
785 let txn = txn.as_mut().unwrap();
786 let txn = txn.as_mut().unwrap();
787 txn.gc(None);
788}
789
790#[no_mangle]
793pub unsafe extern "C" fn ytransaction_writeable(txn: *mut Transaction) -> u8 {
794 assert!(!txn.is_null());
795 if txn.as_ref().unwrap().is_writeable() {
796 1
797 } else {
798 0
799 }
800}
801
802#[no_mangle]
823pub unsafe extern "C" fn ytransaction_json_path(
824 txn: *mut Transaction,
825 json_path: *const c_char,
826) -> *mut JsonPathIter {
827 assert!(!txn.is_null());
828 let txn = txn.as_ref().unwrap();
829
830 let query: String = CStr::from_ptr(json_path).to_str().unwrap().into();
832 let json_path: &'static str = unsafe { std::mem::transmute(query.as_str()) };
834 let json_path = match JsonPath::parse(json_path) {
835 Ok(query) => Box::new(query),
836 Err(_) => return null_mut(),
837 };
838 let json_path_ref: &'static JsonPath = unsafe { std::mem::transmute(json_path.as_ref()) };
840 let inner = txn.json_path(json_path_ref);
841 let iter = Box::new(JsonPathIter {
842 query,
843 json_path,
844 inner,
845 });
846 Box::into_raw(iter)
847}
848
849#[no_mangle]
851pub unsafe extern "C" fn yjson_path_iter_next(iter: *mut JsonPathIter) -> *mut YOutput {
852 assert!(!iter.is_null());
853 let iter = iter.as_mut().unwrap();
854 if let Some(value) = iter.inner.next() {
855 let youtput = YOutput::from(value);
856 Box::into_raw(Box::new(youtput))
857 } else {
858 null_mut()
859 }
860}
861
862#[no_mangle]
864pub unsafe extern "C" fn yjson_path_iter_destroy(iter: *mut JsonPathIter) {
865 if !iter.is_null() {
866 drop(Box::from_raw(iter));
867 }
868}
869
870#[no_mangle]
876pub unsafe extern "C" fn ytype_get(txn: *mut Transaction, name: *const c_char) -> *mut Branch {
877 assert!(!txn.is_null());
878 assert!(!name.is_null());
879
880 let name = CStr::from_ptr(name).to_str().unwrap();
881 if let Some(txt) = txn.as_mut().unwrap().get_text(name) {
884 txt.into_raw_branch()
885 } else {
886 null_mut()
887 }
888}
889
890#[no_mangle]
894pub unsafe extern "C" fn ytext(doc: *mut Doc, name: *const c_char) -> *mut Branch {
895 assert!(!doc.is_null());
896 assert!(!name.is_null());
897
898 let name = CStr::from_ptr(name).to_str().unwrap();
899 let txt = doc.as_mut().unwrap().get_or_insert_text(name);
900 txt.into_raw_branch()
901}
902
903#[no_mangle]
909pub unsafe extern "C" fn yarray(doc: *mut Doc, name: *const c_char) -> *mut Branch {
910 assert!(!doc.is_null());
911 assert!(!name.is_null());
912
913 let name = CStr::from_ptr(name).to_str().unwrap();
914 doc.as_mut()
915 .unwrap()
916 .get_or_insert_array(name)
917 .into_raw_branch()
918}
919
920#[no_mangle]
926pub unsafe extern "C" fn ymap(doc: *mut Doc, name: *const c_char) -> *mut Branch {
927 assert!(!doc.is_null());
928 assert!(!name.is_null());
929
930 let name = CStr::from_ptr(name).to_str().unwrap();
931 doc.as_mut()
932 .unwrap()
933 .get_or_insert_map(name)
934 .into_raw_branch()
935}
936
937#[no_mangle]
941pub unsafe extern "C" fn yxmlfragment(doc: *mut Doc, name: *const c_char) -> *mut Branch {
942 assert!(!doc.is_null());
943 assert!(!name.is_null());
944
945 let name = CStr::from_ptr(name).to_str().unwrap();
946 doc.as_mut()
947 .unwrap()
948 .get_or_insert_xml_fragment(name)
949 .into_raw_branch()
950}
951
952#[no_mangle]
962pub unsafe extern "C" fn ytransaction_state_vector_v1(
963 txn: *const Transaction,
964 len: *mut u32,
965) -> *mut c_char {
966 assert!(!txn.is_null());
967
968 let txn = txn.as_ref().unwrap();
969 let state_vector = txn.state_vector();
970 let binary = state_vector.encode_v1().into_boxed_slice();
971
972 *len = binary.len() as u32;
973 Box::into_raw(binary) as *mut c_char
974}
975
976#[no_mangle]
991pub unsafe extern "C" fn ytransaction_state_diff_v1(
992 txn: *const Transaction,
993 sv: *const c_char,
994 sv_len: u32,
995 len: *mut u32,
996) -> *mut c_char {
997 assert!(!txn.is_null());
998
999 let txn = txn.as_ref().unwrap();
1000 let sv = {
1001 if sv.is_null() {
1002 StateVector::default()
1003 } else {
1004 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
1005 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
1006 sv
1007 } else {
1008 return null_mut();
1009 }
1010 }
1011 };
1012
1013 let mut encoder = EncoderV1::new();
1014 txn.encode_diff(&sv, &mut encoder);
1015 let binary = encoder.to_vec().into_boxed_slice();
1016 *len = binary.len() as u32;
1017 Box::into_raw(binary) as *mut c_char
1018}
1019
1020#[no_mangle]
1035pub unsafe extern "C" fn ytransaction_state_diff_v2(
1036 txn: *const Transaction,
1037 sv: *const c_char,
1038 sv_len: u32,
1039 len: *mut u32,
1040) -> *mut c_char {
1041 assert!(!txn.is_null());
1042
1043 let txn = txn.as_ref().unwrap();
1044 let sv = {
1045 if sv.is_null() {
1046 StateVector::default()
1047 } else {
1048 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
1049 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
1050 sv
1051 } else {
1052 return null_mut();
1053 }
1054 }
1055 };
1056
1057 let mut encoder = EncoderV2::new();
1058 txn.encode_diff(&sv, &mut encoder);
1059 let binary = encoder.to_vec().into_boxed_slice();
1060 *len = binary.len() as u32;
1061 Box::into_raw(binary) as *mut c_char
1062}
1063
1064#[no_mangle]
1068pub unsafe extern "C" fn ytransaction_snapshot(
1069 txn: *const Transaction,
1070 len: *mut u32,
1071) -> *mut c_char {
1072 assert!(!txn.is_null());
1073 let txn = txn.as_ref().unwrap();
1074 let binary = txn.snapshot().encode_v1().into_boxed_slice();
1075
1076 *len = binary.len() as u32;
1077 Box::into_raw(binary) as *mut c_char
1078}
1079
1080#[no_mangle]
1089pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v1(
1090 txn: *const Transaction,
1091 snapshot: *const c_char,
1092 snapshot_len: u32,
1093 len: *mut u32,
1094) -> *mut c_char {
1095 assert!(!txn.is_null());
1096 let txn = txn.as_ref().unwrap();
1097 let snapshot = {
1098 let len = snapshot_len as usize;
1099 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
1100 Snapshot::decode_v1(&data).unwrap()
1101 };
1102 let mut encoder = EncoderV1::new();
1103 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
1104 Err(_) => null_mut(),
1105 Ok(_) => {
1106 let binary = encoder.to_vec().into_boxed_slice();
1107 *len = binary.len() as u32;
1108 Box::into_raw(binary) as *mut c_char
1109 }
1110 }
1111}
1112
1113#[no_mangle]
1122pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v2(
1123 txn: *const Transaction,
1124 snapshot: *const c_char,
1125 snapshot_len: u32,
1126 len: *mut u32,
1127) -> *mut c_char {
1128 assert!(!txn.is_null());
1129 let txn = txn.as_ref().unwrap();
1130 let snapshot = {
1131 let len = snapshot_len as usize;
1132 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
1133 Snapshot::decode_v1(&data).unwrap()
1134 };
1135 let mut encoder = EncoderV2::new();
1136 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
1137 Err(_) => null_mut(),
1138 Ok(_) => {
1139 let binary = encoder.to_vec().into_boxed_slice();
1140 *len = binary.len() as u32;
1141 Box::into_raw(binary) as *mut c_char
1142 }
1143 }
1144}
1145
1146#[no_mangle]
1152pub unsafe extern "C" fn ytransaction_pending_ds(txn: *const Transaction) -> *mut YIdSet {
1153 let txn = txn.as_ref().unwrap();
1154 match txn.store().pending_ds() {
1155 None => null_mut(),
1156 Some(ds) => Box::into_raw(Box::new(YIdSet::new(ds))),
1157 }
1158}
1159
1160#[no_mangle]
1161pub unsafe extern "C" fn ydelete_set_destroy(ds: *mut YIdSet) {
1162 if ds.is_null() {
1163 return;
1164 }
1165 drop(Box::from_raw(ds))
1166}
1167
1168#[no_mangle]
1177pub unsafe extern "C" fn ytransaction_pending_update(
1178 txn: *const Transaction,
1179) -> *mut YPendingUpdate {
1180 let txn = txn.as_ref().unwrap();
1181 match txn.store().pending_update() {
1182 None => null_mut(),
1183 Some(u) => {
1184 let binary = u.update.encode_v1().into_boxed_slice();
1185 let update_len = binary.len() as u32;
1186 let missing = YStateVector::new(&u.missing);
1187 let update = YPendingUpdate {
1188 missing,
1189 update_len,
1190 update_v1: Box::into_raw(binary) as *mut c_char,
1191 };
1192 Box::into_raw(Box::new(update))
1193 }
1194 }
1195}
1196
1197#[repr(C)]
1201pub struct YPendingUpdate {
1202 pub missing: YStateVector,
1205 pub update_v1: *mut c_char,
1207 pub update_len: u32,
1209}
1210
1211#[no_mangle]
1212pub unsafe extern "C" fn ypending_update_destroy(update: *mut YPendingUpdate) {
1213 if update.is_null() {
1214 return;
1215 }
1216 let update = Box::from_raw(update);
1217 drop(update.missing);
1218 ybinary_destroy(update.update_v1, update.update_len);
1219}
1220
1221#[no_mangle]
1225pub unsafe extern "C" fn yupdate_debug_v1(update: *const c_char, update_len: u32) -> *mut c_char {
1226 assert!(!update.is_null());
1227
1228 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1229 if let Ok(u) = Update::decode_v1(data) {
1230 let str = format!("{:#?}", u);
1231 CString::new(str).unwrap().into_raw()
1232 } else {
1233 null_mut()
1234 }
1235}
1236
1237#[no_mangle]
1241pub unsafe extern "C" fn yupdate_debug_v2(update: *const c_char, update_len: u32) -> *mut c_char {
1242 assert!(!update.is_null());
1243
1244 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1245 if let Ok(u) = Update::decode_v2(data) {
1246 let str = format!("{:#?}", u);
1247 CString::new(str).unwrap().into_raw()
1248 } else {
1249 null_mut()
1250 }
1251}
1252
1253#[no_mangle]
1267pub unsafe extern "C" fn ytransaction_apply(
1268 txn: *mut Transaction,
1269 diff: *const c_char,
1270 diff_len: u32,
1271) -> u8 {
1272 assert!(!txn.is_null());
1273 assert!(!diff.is_null());
1274
1275 let update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1276 let mut decoder = DecoderV1::from(update);
1277 match Update::decode(&mut decoder) {
1278 Ok(update) => {
1279 let txn = txn.as_mut().unwrap();
1280 let txn = txn
1281 .as_mut()
1282 .expect("provided transaction was not writeable");
1283 match txn.apply_update(update) {
1284 Ok(_) => 0,
1285 Err(e) => update_err_code(e),
1286 }
1287 }
1288 Err(e) => err_code(e),
1289 }
1290}
1291
1292#[no_mangle]
1306pub unsafe extern "C" fn ytransaction_apply_v2(
1307 txn: *mut Transaction,
1308 diff: *const c_char,
1309 diff_len: u32,
1310) -> u8 {
1311 assert!(!txn.is_null());
1312 assert!(!diff.is_null());
1313
1314 let mut update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1315 match Update::decode_v2(&mut update) {
1316 Ok(update) => {
1317 let txn = txn.as_mut().unwrap();
1318 let txn = txn
1319 .as_mut()
1320 .expect("provided transaction was not writeable");
1321 match txn.apply_update(update) {
1322 Ok(_) => 0,
1323 Err(e) => update_err_code(e),
1324 }
1325 }
1326 Err(e) => err_code(e),
1327 }
1328}
1329
1330pub const ERR_CODE_IO: u8 = 1;
1332
1333pub const ERR_CODE_VAR_INT: u8 = 2;
1335
1336pub const ERR_CODE_EOS: u8 = 3;
1338
1339pub const ERR_CODE_UNEXPECTED_VALUE: u8 = 4;
1341
1342pub const ERR_CODE_INVALID_JSON: u8 = 5;
1344
1345pub const ERR_CODE_OTHER: u8 = 6;
1347
1348pub const ERR_NOT_ENOUGH_MEMORY: u8 = 7;
1350
1351pub const ERR_TYPE_MISMATCH: u8 = 8;
1353
1354pub const ERR_CUSTOM: u8 = 9;
1356
1357pub const ERR_INVALID_PARENT: u8 = 9;
1359
1360fn err_code(e: Error) -> u8 {
1361 match e {
1362 Error::InvalidVarInt => ERR_CODE_VAR_INT,
1363 Error::EndOfBuffer(_) => ERR_CODE_EOS,
1364 Error::UnexpectedValue => ERR_CODE_UNEXPECTED_VALUE,
1365 Error::InvalidJSON(_) => ERR_CODE_INVALID_JSON,
1366 Error::NotEnoughMemory(_) => ERR_NOT_ENOUGH_MEMORY,
1367 Error::TypeMismatch(_) => ERR_TYPE_MISMATCH,
1368 Error::Custom(_) => ERR_CUSTOM,
1369 }
1370}
1371fn update_err_code(e: UpdateError) -> u8 {
1372 match e {
1373 UpdateError::InvalidParent(_, _) => ERR_INVALID_PARENT,
1374 }
1375}
1376
1377#[no_mangle]
1379pub unsafe extern "C" fn ytext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
1380 assert!(!txt.is_null());
1381 let txn = txn.as_ref().unwrap();
1382 let txt = TextRef::from_raw_branch(txt);
1383 txt.len(txn)
1384}
1385
1386#[no_mangle]
1390pub unsafe extern "C" fn ytext_string(txt: *const Branch, txn: *const Transaction) -> *mut c_char {
1391 assert!(!txt.is_null());
1392
1393 let txn = txn.as_ref().unwrap();
1394 let txt = TextRef::from_raw_branch(txt);
1395 let str = txt.get_string(txn);
1396 CString::new(str).unwrap().into_raw()
1397}
1398
1399#[no_mangle]
1410pub unsafe extern "C" fn ytext_insert(
1411 txt: *const Branch,
1412 txn: *mut Transaction,
1413 index: u32,
1414 value: *const c_char,
1415 attrs: *const YInput,
1416) {
1417 assert!(!txt.is_null());
1418 assert!(!txn.is_null());
1419 assert!(!value.is_null());
1420
1421 let chunk = CStr::from_ptr(value).to_str().unwrap();
1422 let txn = txn.as_mut().unwrap();
1423 let txn = txn
1424 .as_mut()
1425 .expect("provided transaction was not writeable");
1426 let txt = TextRef::from_raw_branch(txt);
1427 let index = index as u32;
1428 if attrs.is_null() {
1429 txt.insert(txn, index, chunk)
1430 } else {
1431 if let Some(attrs) = map_attrs(attrs.read().into()) {
1432 txt.insert_with_attributes(txn, index, chunk, attrs)
1433 } else {
1434 panic!("ytext_insert: passed attributes are not of map type")
1435 }
1436 }
1437}
1438
1439#[no_mangle]
1442pub unsafe extern "C" fn ytext_format(
1443 txt: *const Branch,
1444 txn: *mut Transaction,
1445 index: u32,
1446 len: u32,
1447 attrs: *const YInput,
1448) {
1449 assert!(!txt.is_null());
1450 assert!(!txn.is_null());
1451 assert!(!attrs.is_null());
1452
1453 if let Some(attrs) = map_attrs(attrs.read().into()) {
1454 let txt = TextRef::from_raw_branch(txt);
1455 let txn = txn.as_mut().unwrap();
1456 let txn = txn
1457 .as_mut()
1458 .expect("provided transaction was not writeable");
1459 let index = index as u32;
1460 let len = len as u32;
1461 txt.format(txn, index, len, attrs);
1462 } else {
1463 panic!("ytext_format: passed attributes are not of map type")
1464 }
1465}
1466
1467#[no_mangle]
1478pub unsafe extern "C" fn ytext_insert_embed(
1479 txt: *const Branch,
1480 txn: *mut Transaction,
1481 index: u32,
1482 content: *const YInput,
1483 attrs: *const YInput,
1484) {
1485 assert!(!txt.is_null());
1486 assert!(!txn.is_null());
1487 assert!(!content.is_null());
1488
1489 let txn = txn.as_mut().unwrap();
1490 let txn = txn
1491 .as_mut()
1492 .expect("provided transaction was not writeable");
1493 let txt = TextRef::from_raw_branch(txt);
1494 let index = index as u32;
1495 let content = content.read();
1496 if attrs.is_null() {
1497 txt.insert_embed(txn, index, content);
1498 } else {
1499 if let Some(attrs) = map_attrs(attrs.read().into()) {
1500 txt.insert_embed_with_attributes(txn, index, content, attrs);
1501 } else {
1502 panic!("ytext_insert_embed: passed attributes are not of map type")
1503 }
1504 }
1505}
1506
1507#[no_mangle]
1521pub unsafe extern "C" fn ytext_insert_delta(
1522 txt: *const Branch,
1523 txn: *mut Transaction,
1524 delta: *mut YDeltaIn,
1525 delta_len: u32,
1526) {
1527 let txt = TextRef::from_raw_branch(txt);
1528 let txn = txn.as_mut().unwrap();
1529 let txn = txn
1530 .as_mut()
1531 .expect("provided transaction was not writeable");
1532 let delta = std::slice::from_raw_parts(delta, delta_len as usize);
1533 let mut insert = Vec::with_capacity(delta.len());
1534 for chunk in delta {
1535 let d = chunk.as_input();
1536 insert.push(d);
1537 }
1538 txt.apply_delta(txn, insert);
1539}
1540
1541#[no_mangle]
1545pub unsafe extern "C" fn ydelta_input_retain(len: u32, attrs: *const YInput) -> YDeltaIn {
1546 YDeltaIn {
1547 tag: Y_EVENT_CHANGE_RETAIN,
1548 len,
1549 attributes: attrs,
1550 insert: null(),
1551 }
1552}
1553
1554#[no_mangle]
1557pub unsafe extern "C" fn ydelta_input_delete(len: u32) -> YDeltaIn {
1558 YDeltaIn {
1559 tag: Y_EVENT_CHANGE_DELETE,
1560 len,
1561 attributes: null(),
1562 insert: null(),
1563 }
1564}
1565
1566#[no_mangle]
1572pub unsafe extern "C" fn ydelta_input_insert(
1573 data: *const YInput,
1574 attrs: *const YInput,
1575) -> YDeltaIn {
1576 YDeltaIn {
1577 tag: Y_EVENT_CHANGE_ADD,
1578 len: 1,
1579 attributes: attrs,
1580 insert: data,
1581 }
1582}
1583
1584fn map_attrs(attrs: Any) -> Option<Attrs> {
1585 if let Any::Map(attrs) = attrs {
1586 let attrs = attrs
1587 .iter()
1588 .map(|(k, v)| (k.as_str().into(), v.clone()))
1589 .collect();
1590 Some(attrs)
1591 } else {
1592 None
1593 }
1594}
1595
1596#[no_mangle]
1605pub unsafe extern "C" fn ytext_remove_range(
1606 txt: *const Branch,
1607 txn: *mut Transaction,
1608 index: u32,
1609 length: u32,
1610) {
1611 assert!(!txt.is_null());
1612 assert!(!txn.is_null());
1613
1614 let txn = txn.as_mut().unwrap();
1615 let txn = txn
1616 .as_mut()
1617 .expect("provided transaction was not writeable");
1618 let txt = TextRef::from_raw_branch(txt);
1619 txt.remove_range(txn, index as u32, length as u32)
1620}
1621
1622#[no_mangle]
1624pub unsafe extern "C" fn yarray_len(array: *const Branch) -> u32 {
1625 assert!(!array.is_null());
1626
1627 let array = array.as_ref().unwrap();
1628 array.len() as u32
1629}
1630
1631#[no_mangle]
1636pub unsafe extern "C" fn yarray_get(
1637 array: *const Branch,
1638 txn: *const Transaction,
1639 index: u32,
1640) -> *mut YOutput {
1641 assert!(!array.is_null());
1642
1643 let array = ArrayRef::from_raw_branch(array);
1644 let txn = txn.as_ref().unwrap();
1645
1646 if let Some(val) = array.get(txn, index as u32) {
1647 Box::into_raw(Box::new(YOutput::from(val)))
1648 } else {
1649 std::ptr::null_mut()
1650 }
1651}
1652
1653#[no_mangle]
1664pub unsafe extern "C" fn yarray_get_json(
1665 array: *const Branch,
1666 txn: *const Transaction,
1667 index: u32,
1668) -> *mut c_char {
1669 assert!(!array.is_null());
1670
1671 let array = ArrayRef::from_raw_branch(array);
1672 let txn = txn.as_ref().unwrap();
1673
1674 if let Some(val) = array.get(txn, index as u32) {
1675 let any = val.to_json(txn);
1676 let json = match serde_json::to_string(&any) {
1677 Ok(json) => json,
1678 Err(_) => return std::ptr::null_mut(),
1679 };
1680 CString::new(json).unwrap().into_raw()
1681 } else {
1682 std::ptr::null_mut()
1683 }
1684}
1685
1686#[no_mangle]
1697pub unsafe extern "C" fn yarray_insert_range(
1698 array: *const Branch,
1699 txn: *mut Transaction,
1700 index: u32,
1701 items: *const YInput,
1702 items_len: u32,
1703) {
1704 assert!(!array.is_null());
1705 assert!(!txn.is_null());
1706 assert!(!items.is_null());
1707
1708 let array = ArrayRef::from_raw_branch(array);
1709 let txn = txn.as_mut().unwrap();
1710 let txn = txn
1711 .as_mut()
1712 .expect("provided transaction was not writeable");
1713
1714 let ptr = items;
1715 let mut i = 0;
1716 let mut j = index as u32;
1717 let len = items_len as isize;
1718 while i < len {
1719 let mut vec: Vec<Any> = Vec::default();
1720
1721 while i < len {
1723 let val = ptr.offset(i).read();
1724 if val.tag <= 0 {
1725 let any = val.into();
1726 vec.push(any);
1727 } else {
1728 break;
1729 }
1730 i += 1;
1731 }
1732
1733 if !vec.is_empty() {
1734 let len = vec.len() as u32;
1735 array.insert_range(txn, j, vec);
1736 j += len;
1737 } else {
1738 let val = ptr.offset(i).read();
1739 array.insert(txn, j, val);
1740 i += 1;
1741 j += 1;
1742 }
1743 }
1744}
1745
1746#[no_mangle]
1750pub unsafe extern "C" fn yarray_remove_range(
1751 array: *const Branch,
1752 txn: *mut Transaction,
1753 index: u32,
1754 len: u32,
1755) {
1756 assert!(!array.is_null());
1757 assert!(!txn.is_null());
1758
1759 let array = ArrayRef::from_raw_branch(array);
1760 let txn = txn.as_mut().unwrap();
1761 let txn = txn
1762 .as_mut()
1763 .expect("provided transaction was not writeable");
1764
1765 array.remove_range(txn, index as u32, len as u32)
1766}
1767
1768#[no_mangle]
1774pub unsafe extern "C" fn yarray_iter(
1775 array: *const Branch,
1776 txn: *mut Transaction,
1777) -> *mut ArrayIter {
1778 assert!(!array.is_null());
1779 assert!(!txn.is_null());
1780
1781 let txn = txn.as_ref().unwrap();
1782 let array = &ArrayRef::from_raw_branch(array) as *const ArrayRef;
1783 Box::into_raw(Box::new(ArrayIter(array.as_ref().unwrap().iter(txn))))
1784}
1785
1786#[no_mangle]
1788pub unsafe extern "C" fn yarray_iter_destroy(iter: *mut ArrayIter) {
1789 if !iter.is_null() {
1790 drop(Box::from_raw(iter))
1791 }
1792}
1793
1794#[no_mangle]
1799pub unsafe extern "C" fn yarray_iter_next(iterator: *mut ArrayIter) -> *mut YOutput {
1800 assert!(!iterator.is_null());
1801
1802 let iter = iterator.as_mut().unwrap();
1803 if let Some(v) = iter.0.next() {
1804 let out = YOutput::from(v);
1805 Box::into_raw(Box::new(out))
1806 } else {
1807 std::ptr::null_mut()
1808 }
1809}
1810
1811#[no_mangle]
1816pub unsafe extern "C" fn ymap_iter(map: *const Branch, txn: *const Transaction) -> *mut MapIter {
1817 assert!(!map.is_null());
1818
1819 let txn = txn.as_ref().unwrap();
1820 let map = &MapRef::from_raw_branch(map) as *const MapRef;
1821 Box::into_raw(Box::new(MapIter(map.as_ref().unwrap().iter(txn))))
1822}
1823
1824#[no_mangle]
1826pub unsafe extern "C" fn ymap_iter_destroy(iter: *mut MapIter) {
1827 if !iter.is_null() {
1828 drop(Box::from_raw(iter))
1829 }
1830}
1831
1832#[no_mangle]
1838pub unsafe extern "C" fn ymap_iter_next(iter: *mut MapIter) -> *mut YMapEntry {
1839 assert!(!iter.is_null());
1840
1841 let iter = iter.as_mut().unwrap();
1842 if let Some((key, value)) = iter.0.next() {
1843 let output = YOutput::from(value);
1844 Box::into_raw(Box::new(YMapEntry::new(key, Box::new(output))))
1845 } else {
1846 std::ptr::null_mut()
1847 }
1848}
1849
1850#[no_mangle]
1852pub unsafe extern "C" fn ymap_len(map: *const Branch, txn: *const Transaction) -> u32 {
1853 assert!(!map.is_null());
1854
1855 let txn = txn.as_ref().unwrap();
1856 let map = MapRef::from_raw_branch(map);
1857
1858 map.len(txn)
1859}
1860
1861#[no_mangle]
1870pub unsafe extern "C" fn ymap_insert(
1871 map: *const Branch,
1872 txn: *mut Transaction,
1873 key: *const c_char,
1874 value: *const YInput,
1875) {
1876 assert!(!map.is_null());
1877 assert!(!txn.is_null());
1878 assert!(!key.is_null());
1879 assert!(!value.is_null());
1880
1881 let cstr = CStr::from_ptr(key);
1882 let key = cstr.to_str().unwrap().to_string();
1883
1884 let map = MapRef::from_raw_branch(map);
1885 let txn = txn.as_mut().unwrap();
1886 let txn = txn
1887 .as_mut()
1888 .expect("provided transaction was not writeable");
1889
1890 map.insert(txn, key, value.read());
1891}
1892
1893#[no_mangle]
1898pub unsafe extern "C" fn ymap_remove(
1899 map: *const Branch,
1900 txn: *mut Transaction,
1901 key: *const c_char,
1902) -> u8 {
1903 assert!(!map.is_null());
1904 assert!(!txn.is_null());
1905 assert!(!key.is_null());
1906
1907 let key = CStr::from_ptr(key).to_str().unwrap();
1908
1909 let map = MapRef::from_raw_branch(map);
1910 let txn = txn.as_mut().unwrap();
1911 let txn = txn
1912 .as_mut()
1913 .expect("provided transaction was not writeable");
1914
1915 if let Some(_) = map.remove(txn, key) {
1916 Y_TRUE
1917 } else {
1918 Y_FALSE
1919 }
1920}
1921
1922#[no_mangle]
1928pub unsafe extern "C" fn ymap_get(
1929 map: *const Branch,
1930 txn: *const Transaction,
1931 key: *const c_char,
1932) -> *mut YOutput {
1933 assert!(!map.is_null());
1934 assert!(!key.is_null());
1935 assert!(!txn.is_null());
1936
1937 let txn = txn.as_ref().unwrap();
1938 let key = CStr::from_ptr(key).to_str().unwrap();
1939
1940 let map = MapRef::from_raw_branch(map);
1941
1942 if let Some(value) = map.get(txn, key) {
1943 let output = YOutput::from(value);
1944 Box::into_raw(Box::new(output))
1945 } else {
1946 std::ptr::null_mut()
1947 }
1948}
1949
1950#[no_mangle]
1959pub unsafe extern "C" fn ymap_get_json(
1960 map: *const Branch,
1961 txn: *const Transaction,
1962 key: *const c_char,
1963) -> *mut c_char {
1964 assert!(!map.is_null());
1965 assert!(!key.is_null());
1966 assert!(!txn.is_null());
1967
1968 let txn = txn.as_ref().unwrap();
1969 let key = CStr::from_ptr(key).to_str().unwrap();
1970
1971 let map = MapRef::from_raw_branch(map);
1972
1973 if let Some(value) = map.get(txn, key) {
1974 let any = value.to_json(txn);
1975 match serde_json::to_string(&any) {
1976 Ok(json) => CString::new(json).unwrap().into_raw(),
1977 Err(_) => std::ptr::null_mut(),
1978 }
1979 } else {
1980 std::ptr::null_mut()
1981 }
1982}
1983
1984#[no_mangle]
1986pub unsafe extern "C" fn ymap_remove_all(map: *const Branch, txn: *mut Transaction) {
1987 assert!(!map.is_null());
1988 assert!(!txn.is_null());
1989
1990 let map = MapRef::from_raw_branch(map);
1991 let txn = txn.as_mut().unwrap();
1992 let txn = txn
1993 .as_mut()
1994 .expect("provided transaction was not writeable");
1995
1996 map.clear(txn);
1997}
1998
1999#[no_mangle]
2005pub unsafe extern "C" fn yxmlelem_tag(xml: *const Branch) -> *mut c_char {
2006 assert!(!xml.is_null());
2007 let xml = XmlElementRef::from_raw_branch(xml);
2008 if let Some(tag) = xml.try_tag() {
2009 CString::new(tag.deref()).unwrap().into_raw()
2010 } else {
2011 null_mut()
2012 }
2013}
2014
2015#[no_mangle]
2021pub unsafe extern "C" fn yxmlelem_string(
2022 xml: *const Branch,
2023 txn: *const Transaction,
2024) -> *mut c_char {
2025 assert!(!xml.is_null());
2026 assert!(!txn.is_null());
2027
2028 let txn = txn.as_ref().unwrap();
2029 let xml = XmlElementRef::from_raw_branch(xml);
2030
2031 let str = xml.get_string(txn);
2032 CString::new(str).unwrap().into_raw()
2033}
2034
2035#[no_mangle]
2041pub unsafe extern "C" fn yxmlelem_insert_attr(
2042 xml: *const Branch,
2043 txn: *mut Transaction,
2044 attr_name: *const c_char,
2045 attr_value: *const YInput,
2046) {
2047 assert!(!xml.is_null());
2048 assert!(!txn.is_null());
2049 assert!(!attr_name.is_null());
2050 assert!(!attr_value.is_null());
2051
2052 let xml = XmlElementRef::from_raw_branch(xml);
2053 let txn = txn.as_mut().unwrap();
2054 let txn = txn
2055 .as_mut()
2056 .expect("provided transaction was not writeable");
2057
2058 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2059
2060 xml.insert_attribute(txn, key, attr_value.read());
2061}
2062
2063#[no_mangle]
2067pub unsafe extern "C" fn yxmlelem_remove_attr(
2068 xml: *const Branch,
2069 txn: *mut Transaction,
2070 attr_name: *const c_char,
2071) {
2072 assert!(!xml.is_null());
2073 assert!(!txn.is_null());
2074 assert!(!attr_name.is_null());
2075
2076 let xml = XmlElementRef::from_raw_branch(xml);
2077 let txn = txn.as_mut().unwrap();
2078 let txn = txn
2079 .as_mut()
2080 .expect("provided transaction was not writeable");
2081
2082 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2083 xml.remove_attribute(txn, &key);
2084}
2085
2086#[no_mangle]
2092pub unsafe extern "C" fn yxmlelem_get_attr(
2093 xml: *const Branch,
2094 txn: *const Transaction,
2095 attr_name: *const c_char,
2096) -> *mut YOutput {
2097 assert!(!xml.is_null());
2098 assert!(!attr_name.is_null());
2099 assert!(!txn.is_null());
2100
2101 let xml = XmlElementRef::from_raw_branch(xml);
2102
2103 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2104 let txn = txn.as_ref().unwrap();
2105 if let Some(value) = xml.get_attribute(txn, key) {
2106 let output = YOutput::from(value);
2107 Box::into_raw(Box::new(output))
2108 } else {
2109 std::ptr::null_mut()
2110 }
2111}
2112
2113#[no_mangle]
2118pub unsafe extern "C" fn yxmlelem_attr_iter(
2119 xml: *const Branch,
2120 txn: *const Transaction,
2121) -> *mut Attributes {
2122 assert!(!xml.is_null());
2123 assert!(!txn.is_null());
2124
2125 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2126 let txn = txn.as_ref().unwrap();
2127 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
2128}
2129
2130#[no_mangle]
2135pub unsafe extern "C" fn yxmltext_attr_iter(
2136 xml: *const Branch,
2137 txn: *const Transaction,
2138) -> *mut Attributes {
2139 assert!(!xml.is_null());
2140 assert!(!txn.is_null());
2141
2142 let xml = &XmlTextRef::from_raw_branch(xml) as *const XmlTextRef;
2143 let txn = txn.as_ref().unwrap();
2144 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
2145}
2146
2147#[no_mangle]
2150pub unsafe extern "C" fn yxmlattr_iter_destroy(iterator: *mut Attributes) {
2151 if !iterator.is_null() {
2152 drop(Box::from_raw(iterator))
2153 }
2154}
2155
2156#[no_mangle]
2162pub unsafe extern "C" fn yxmlattr_iter_next(iterator: *mut Attributes) -> *mut YXmlAttr {
2163 assert!(!iterator.is_null());
2164
2165 let iter = iterator.as_mut().unwrap();
2166
2167 if let Some((name, value)) = iter.0.next() {
2168 Box::into_raw(Box::new(YXmlAttr {
2169 name: CString::new(name).unwrap().into_raw(),
2170 value: Box::into_raw(Box::new(YOutput::from(value))),
2171 }))
2172 } else {
2173 std::ptr::null_mut()
2174 }
2175}
2176
2177#[no_mangle]
2185pub unsafe extern "C" fn yxml_next_sibling(
2186 xml: *const Branch,
2187 txn: *const Transaction,
2188) -> *mut YOutput {
2189 assert!(!xml.is_null());
2190 assert!(!txn.is_null());
2191
2192 let xml = XmlElementRef::from_raw_branch(xml);
2193 let txn = txn.as_ref().unwrap();
2194
2195 let mut siblings = xml.siblings(txn);
2196 if let Some(next) = siblings.next() {
2197 match next {
2198 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2199 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2200 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2201 }
2202 } else {
2203 null_mut()
2204 }
2205}
2206
2207#[no_mangle]
2213pub unsafe extern "C" fn yxml_prev_sibling(
2214 xml: *const Branch,
2215 txn: *const Transaction,
2216) -> *mut YOutput {
2217 assert!(!xml.is_null());
2218 assert!(!txn.is_null());
2219
2220 let xml = XmlElementRef::from_raw_branch(xml);
2221 let txn = txn.as_ref().unwrap();
2222
2223 let mut siblings = xml.siblings(txn);
2224 if let Some(next) = siblings.next_back() {
2225 match next {
2226 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2227 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2228 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2229 }
2230 } else {
2231 null_mut()
2232 }
2233}
2234
2235#[no_mangle]
2238pub unsafe extern "C" fn yxmlelem_parent(xml: *const Branch) -> *mut Branch {
2239 assert!(!xml.is_null());
2240
2241 let xml = XmlElementRef::from_raw_branch(xml);
2242
2243 if let Some(parent) = xml.parent() {
2244 let branch = parent.as_ptr();
2245 branch.deref() as *const Branch as *mut Branch
2246 } else {
2247 std::ptr::null_mut()
2248 }
2249}
2250
2251#[no_mangle]
2254pub unsafe extern "C" fn yxmlelem_child_len(xml: *const Branch, txn: *const Transaction) -> u32 {
2255 assert!(!xml.is_null());
2256 assert!(!txn.is_null());
2257
2258 let txn = txn.as_ref().unwrap();
2259 let xml = XmlElementRef::from_raw_branch(xml);
2260
2261 xml.len(txn) as u32
2262}
2263
2264#[no_mangle]
2269pub unsafe extern "C" fn yxmlelem_first_child(xml: *const Branch) -> *mut YOutput {
2270 assert!(!xml.is_null());
2271
2272 let xml = XmlElementRef::from_raw_branch(xml);
2273
2274 if let Some(value) = xml.first_child() {
2275 match value {
2276 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2277 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2278 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2279 }
2280 } else {
2281 std::ptr::null_mut()
2282 }
2283}
2284
2285#[no_mangle]
2291pub unsafe extern "C" fn yxmlelem_tree_walker(
2292 xml: *const Branch,
2293 txn: *const Transaction,
2294) -> *mut TreeWalker {
2295 assert!(!xml.is_null());
2296 assert!(!txn.is_null());
2297
2298 let txn = txn.as_ref().unwrap();
2299 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2300 Box::into_raw(Box::new(TreeWalker(xml.as_ref().unwrap().successors(txn))))
2301}
2302
2303#[no_mangle]
2305pub unsafe extern "C" fn yxmlelem_tree_walker_destroy(iter: *mut TreeWalker) {
2306 if !iter.is_null() {
2307 drop(Box::from_raw(iter))
2308 }
2309}
2310
2311#[no_mangle]
2316pub unsafe extern "C" fn yxmlelem_tree_walker_next(iterator: *mut TreeWalker) -> *mut YOutput {
2317 assert!(!iterator.is_null());
2318
2319 let iter = iterator.as_mut().unwrap();
2320
2321 if let Some(next) = iter.0.next() {
2322 match next {
2323 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2324 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2325 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2326 }
2327 } else {
2328 std::ptr::null_mut()
2329 }
2330}
2331
2332#[no_mangle]
2341pub unsafe extern "C" fn yxmlelem_insert_elem(
2342 xml: *const Branch,
2343 txn: *mut Transaction,
2344 index: u32,
2345 name: *const c_char,
2346) -> *mut Branch {
2347 assert!(!xml.is_null());
2348 assert!(!txn.is_null());
2349 assert!(!name.is_null());
2350
2351 let xml = XmlElementRef::from_raw_branch(xml);
2352 let txn = txn.as_mut().unwrap();
2353 let txn = txn
2354 .as_mut()
2355 .expect("provided transaction was not writeable");
2356
2357 let name = CStr::from_ptr(name).to_str().unwrap();
2358 xml.insert(txn, index as u32, XmlElementPrelim::empty(name))
2359 .into_raw_branch()
2360}
2361
2362#[no_mangle]
2368pub unsafe extern "C" fn yxmlelem_insert_text(
2369 xml: *const Branch,
2370 txn: *mut Transaction,
2371 index: u32,
2372) -> *mut Branch {
2373 assert!(!xml.is_null());
2374 assert!(!txn.is_null());
2375
2376 let xml = XmlElementRef::from_raw_branch(xml);
2377 let txn = txn.as_mut().unwrap();
2378 let txn = txn
2379 .as_mut()
2380 .expect("provided transaction was not writeable");
2381 xml.insert(txn, index as u32, XmlTextPrelim::new(""))
2382 .into_raw_branch()
2383}
2384
2385#[no_mangle]
2389pub unsafe extern "C" fn yxmlelem_remove_range(
2390 xml: *const Branch,
2391 txn: *mut Transaction,
2392 index: u32,
2393 len: u32,
2394) {
2395 assert!(!xml.is_null());
2396 assert!(!txn.is_null());
2397
2398 let xml = XmlElementRef::from_raw_branch(xml);
2399 let txn = txn.as_mut().unwrap();
2400 let txn = txn
2401 .as_mut()
2402 .expect("provided transaction was not writeable");
2403
2404 xml.remove_range(txn, index as u32, len as u32)
2405}
2406
2407#[no_mangle]
2413pub unsafe extern "C" fn yxmlelem_get(
2414 xml: *const Branch,
2415 txn: *const Transaction,
2416 index: u32,
2417) -> *const YOutput {
2418 assert!(!xml.is_null());
2419 assert!(!txn.is_null());
2420
2421 let xml = XmlElementRef::from_raw_branch(xml);
2422 let txn = txn.as_ref().unwrap();
2423
2424 if let Some(child) = xml.get(txn, index as u32) {
2425 match child {
2426 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2427 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2428 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2429 }
2430 } else {
2431 std::ptr::null()
2432 }
2433}
2434
2435#[no_mangle]
2438pub unsafe extern "C" fn yxmltext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
2439 assert!(!txt.is_null());
2440 assert!(!txn.is_null());
2441
2442 let txn = txn.as_ref().unwrap();
2443 let txt = XmlTextRef::from_raw_branch(txt);
2444
2445 txt.len(txn) as u32
2446}
2447
2448#[no_mangle]
2452pub unsafe extern "C" fn yxmltext_string(
2453 txt: *const Branch,
2454 txn: *const Transaction,
2455) -> *mut c_char {
2456 assert!(!txt.is_null());
2457 assert!(!txn.is_null());
2458
2459 let txn = txn.as_ref().unwrap();
2460 let txt = XmlTextRef::from_raw_branch(txt);
2461
2462 let str = txt.get_string(txn);
2463 CString::new(str).unwrap().into_raw()
2464}
2465
2466#[no_mangle]
2477pub unsafe extern "C" fn yxmltext_insert(
2478 txt: *const Branch,
2479 txn: *mut Transaction,
2480 index: u32,
2481 str: *const c_char,
2482 attrs: *const YInput,
2483) {
2484 assert!(!txt.is_null());
2485 assert!(!txn.is_null());
2486 assert!(!str.is_null());
2487
2488 let txt = XmlTextRef::from_raw_branch(txt);
2489 let txn = txn.as_mut().unwrap();
2490 let txn = txn
2491 .as_mut()
2492 .expect("provided transaction was not writeable");
2493 let chunk = CStr::from_ptr(str).to_str().unwrap();
2494
2495 if attrs.is_null() {
2496 txt.insert(txn, index as u32, chunk)
2497 } else {
2498 if let Some(attrs) = map_attrs(attrs.read().into()) {
2499 txt.insert_with_attributes(txn, index as u32, chunk, attrs)
2500 } else {
2501 panic!("yxmltext_insert: passed attributes are not of map type")
2502 }
2503 }
2504}
2505
2506#[no_mangle]
2517pub unsafe extern "C" fn yxmltext_insert_embed(
2518 txt: *const Branch,
2519 txn: *mut Transaction,
2520 index: u32,
2521 content: *const YInput,
2522 attrs: *const YInput,
2523) {
2524 assert!(!txt.is_null());
2525 assert!(!txn.is_null());
2526 assert!(!content.is_null());
2527
2528 let txn = txn.as_mut().unwrap();
2529 let txn = txn
2530 .as_mut()
2531 .expect("provided transaction was not writeable");
2532 let txt = XmlTextRef::from_raw_branch(txt);
2533 let index = index as u32;
2534 let content = content.read();
2535 if attrs.is_null() {
2536 txt.insert_embed(txn, index, content);
2537 } else {
2538 if let Some(attrs) = map_attrs(attrs.read().into()) {
2539 txt.insert_embed_with_attributes(txn, index, content, attrs);
2540 } else {
2541 panic!("yxmltext_insert_embed: passed attributes are not of map type")
2542 }
2543 }
2544}
2545
2546#[no_mangle]
2549pub unsafe extern "C" fn yxmltext_format(
2550 txt: *const Branch,
2551 txn: *mut Transaction,
2552 index: u32,
2553 len: u32,
2554 attrs: *const YInput,
2555) {
2556 assert!(!txt.is_null());
2557 assert!(!txn.is_null());
2558 assert!(!attrs.is_null());
2559
2560 if let Some(attrs) = map_attrs(attrs.read().into()) {
2561 let txt = XmlTextRef::from_raw_branch(txt);
2562 let txn = txn.as_mut().unwrap();
2563 let txn = txn
2564 .as_mut()
2565 .expect("provided transaction was not writeable");
2566 let index = index as u32;
2567 let len = len as u32;
2568 txt.format(txn, index, len, attrs);
2569 } else {
2570 panic!("yxmltext_format: passed attributes are not of map type")
2571 }
2572}
2573
2574#[no_mangle]
2583pub unsafe extern "C" fn yxmltext_remove_range(
2584 txt: *const Branch,
2585 txn: *mut Transaction,
2586 idx: u32,
2587 len: u32,
2588) {
2589 assert!(!txt.is_null());
2590 assert!(!txn.is_null());
2591
2592 let txt = XmlTextRef::from_raw_branch(txt);
2593 let txn = txn.as_mut().unwrap();
2594 let txn = txn
2595 .as_mut()
2596 .expect("provided transaction was not writeable");
2597 txt.remove_range(txn, idx as u32, len as u32)
2598}
2599
2600#[no_mangle]
2606pub unsafe extern "C" fn yxmltext_insert_attr(
2607 txt: *const Branch,
2608 txn: *mut Transaction,
2609 attr_name: *const c_char,
2610 attr_value: *const YInput,
2611) {
2612 assert!(!txt.is_null());
2613 assert!(!txn.is_null());
2614 assert!(!attr_name.is_null());
2615 assert!(!attr_value.is_null());
2616
2617 let txt = XmlTextRef::from_raw_branch(txt);
2618 let txn = txn.as_mut().unwrap();
2619 let txn = txn
2620 .as_mut()
2621 .expect("provided transaction was not writeable");
2622
2623 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2624
2625 txt.insert_attribute(txn, name, attr_value.read());
2626}
2627
2628#[no_mangle]
2632pub unsafe extern "C" fn yxmltext_remove_attr(
2633 txt: *const Branch,
2634 txn: *mut Transaction,
2635 attr_name: *const c_char,
2636) {
2637 assert!(!txt.is_null());
2638 assert!(!txn.is_null());
2639 assert!(!attr_name.is_null());
2640
2641 let txt = XmlTextRef::from_raw_branch(txt);
2642 let txn = txn.as_mut().unwrap();
2643 let txn = txn
2644 .as_mut()
2645 .expect("provided transaction was not writeable");
2646 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2647
2648 txt.remove_attribute(txn, &name)
2649}
2650
2651#[no_mangle]
2657pub unsafe extern "C" fn yxmltext_get_attr(
2658 txt: *const Branch,
2659 txn: *const Transaction,
2660 attr_name: *const c_char,
2661) -> *mut YOutput {
2662 assert!(!txt.is_null());
2663 assert!(!attr_name.is_null());
2664 assert!(!txn.is_null());
2665
2666 let txn = txn.as_ref().unwrap();
2667 let txt = XmlTextRef::from_raw_branch(txt);
2668 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2669
2670 if let Some(value) = txt.get_attribute(txn, name) {
2671 let output = YOutput::from(value);
2672 Box::into_raw(Box::new(output))
2673 } else {
2674 std::ptr::null_mut()
2675 }
2676}
2677
2678#[no_mangle]
2684pub unsafe extern "C" fn ytext_chunks(
2685 txt: *const Branch,
2686 txn: *const Transaction,
2687 chunks_len: *mut u32,
2688) -> *mut YChunk {
2689 assert!(!txt.is_null());
2690 assert!(!txn.is_null());
2691
2692 let txt = TextRef::from_raw_branch(txt);
2693 let txn = txn.as_ref().unwrap();
2694
2695 let diffs = txt.diff(txn, YChange::identity);
2696 let chunks: Vec<_> = diffs.into_iter().map(YChunk::from).collect();
2697 let out = chunks.into_boxed_slice();
2698 *chunks_len = out.len() as u32;
2699 Box::into_raw(out) as *mut _
2700}
2701
2702#[no_mangle]
2704pub unsafe extern "C" fn ychunks_destroy(chunks: *mut YChunk, len: u32) {
2705 drop(Vec::from_raw_parts(chunks, len as usize, len as usize));
2706}
2707
2708pub const YCHANGE_ADD: i8 = 1;
2709pub const YCHANGE_RETAIN: i8 = 0;
2710pub const YCHANGE_REMOVE: i8 = -1;
2711
2712#[repr(C)]
2714pub struct YChunk {
2715 pub data: YOutput,
2718 pub fmt_len: u32,
2720 pub fmt: *mut YMapEntry,
2722}
2723
2724impl From<Diff<YChange>> for YChunk {
2725 fn from(diff: Diff<YChange>) -> Self {
2726 let data = YOutput::from(diff.insert);
2727 let mut fmt_len = 0;
2728 let fmt = if let Some(attrs) = diff.attributes {
2729 fmt_len = attrs.len() as u32;
2730 let mut fmt = Vec::with_capacity(attrs.len());
2731 for (k, v) in attrs.into_iter() {
2732 let output = YOutput::from(&v); let e = YMapEntry::new(k.as_ref(), Box::new(output));
2734 fmt.push(e);
2735 }
2736 Box::into_raw(fmt.into_boxed_slice()) as *mut _
2737 } else {
2738 null_mut()
2739 };
2740 YChunk { data, fmt_len, fmt }
2741 }
2742}
2743
2744impl Drop for YChunk {
2745 fn drop(&mut self) {
2746 if !self.fmt.is_null() {
2747 drop(unsafe {
2748 Vec::from_raw_parts(self.fmt, self.fmt_len as usize, self.fmt_len as usize)
2749 });
2750 }
2751 }
2752}
2753
2754#[repr(C)]
2761pub struct YInput {
2762 pub tag: i8,
2779
2780 pub len: u32,
2789
2790 value: YInputContent,
2792}
2793
2794impl YInput {
2795 fn into(self) -> Any {
2796 let tag = self.tag;
2797 unsafe {
2798 match tag {
2799 Y_JSON_STR => {
2800 let str = CStr::from_ptr(self.value.str).to_str().unwrap().into();
2801 Any::String(str)
2802 }
2803 Y_JSON => {
2804 let json_str = CStr::from_ptr(self.value.str).to_str().unwrap();
2805 serde_json::from_str(json_str).unwrap()
2806 }
2807 Y_JSON_NULL => Any::Null,
2808 Y_JSON_UNDEF => Any::Undefined,
2809 Y_JSON_INT => Any::Number(Number::Int(self.value.integer)),
2810 Y_JSON_NUM => Any::Number(Number::Float(self.value.num)),
2811 Y_JSON_BOOL => Any::Bool(if self.value.flag == 0 { false } else { true }),
2812 Y_JSON_BUF => Any::from(std::slice::from_raw_parts(
2813 self.value.buf as *mut u8,
2814 self.len as usize,
2815 )),
2816 Y_JSON_ARR => {
2817 let ptr = self.value.values;
2818 let mut dst: Vec<Any> = Vec::with_capacity(self.len as usize);
2819 let mut i = 0;
2820 while i < self.len as isize {
2821 let value = ptr.offset(i).read();
2822 let any = value.into();
2823 dst.push(any);
2824 i += 1;
2825 }
2826 Any::from(dst)
2827 }
2828 Y_JSON_MAP => {
2829 let mut dst = HashMap::with_capacity(self.len as usize);
2830 let keys = self.value.map.keys;
2831 let values = self.value.map.values;
2832 let mut i = 0;
2833 while i < self.len as isize {
2834 let key = CStr::from_ptr(keys.offset(i).read())
2835 .to_str()
2836 .unwrap()
2837 .to_owned();
2838 let value = values.offset(i).read().into();
2839 dst.insert(key, value);
2840 i += 1;
2841 }
2842 Any::from(dst)
2843 }
2844 Y_DOC => Any::Undefined,
2845 other => panic!("Cannot convert input - unknown tag: {}", other),
2846 }
2847 }
2848 }
2849}
2850
2851impl Into<EmbedPrelim<YInput>> for YInput {
2852 fn into(self) -> EmbedPrelim<YInput> {
2853 if self.tag <= 0 {
2854 EmbedPrelim::Primitive(self.into())
2855 } else {
2856 EmbedPrelim::Shared(self)
2857 }
2858 }
2859}
2860
2861#[repr(C)]
2862union YInputContent {
2863 flag: u8,
2864 num: f64,
2865 integer: i64,
2866 str: *mut c_char,
2867 buf: *mut c_char,
2868 values: *mut YInput,
2869 map: ManuallyDrop<YMapInputData>,
2870 doc: *mut Doc,
2871 weak: *const Weak,
2872}
2873
2874#[repr(C)]
2875struct YMapInputData {
2876 keys: *mut *mut c_char,
2877 values: *mut YInput,
2878}
2879
2880impl Drop for YInput {
2881 fn drop(&mut self) {}
2882}
2883
2884impl Prelim for YInput {
2885 type Return = Unused;
2886
2887 fn into_content<'doc>(self, _: &mut yrs::TransactionMut<'doc>) -> (ItemContent, Option<Self>) {
2888 unsafe {
2889 if self.tag <= 0 {
2890 (ItemContent::Any(vec![self.into()]), None)
2891 } else if self.tag == Y_DOC {
2892 let doc = self.value.doc.as_ref().unwrap();
2893 (ItemContent::Doc(None, doc.clone()), None)
2894 } else {
2895 let type_ref = match self.tag {
2896 Y_MAP => TypeRef::Map,
2897 Y_ARRAY => TypeRef::Array,
2898 Y_TEXT => TypeRef::Text,
2899 Y_XML_TEXT => TypeRef::XmlText,
2900 Y_XML_ELEM => {
2901 let name: Arc<str> =
2902 CStr::from_ptr(self.value.str).to_str().unwrap().into();
2903 TypeRef::XmlElement(name)
2904 }
2905 Y_WEAK_LINK => {
2906 let source = Arc::from_raw(self.value.weak);
2907 TypeRef::WeakLink(source)
2908 }
2909 Y_XML_FRAG => TypeRef::XmlFragment,
2910 other => panic!("unrecognized YInput tag: {}", other),
2911 };
2912 let inner = Branch::new(type_ref);
2913 (ItemContent::Type(inner), Some(self))
2914 }
2915 }
2916 }
2917
2918 fn integrate(self, txn: &mut yrs::TransactionMut, inner_ref: BranchPtr) {
2919 unsafe {
2920 match self.tag {
2921 Y_MAP => {
2922 let map = MapRef::from(inner_ref);
2923 let keys = self.value.map.keys;
2924 let values = self.value.map.values;
2925 let mut i = 0;
2926 while i < self.len as isize {
2927 let key = CStr::from_ptr(keys.offset(i).read())
2928 .to_str()
2929 .unwrap()
2930 .to_owned();
2931 let value = values.offset(i).read();
2932 map.insert(txn, key, value);
2933 i += 1;
2934 }
2935 }
2936 Y_ARRAY => {
2937 let array = ArrayRef::from(inner_ref);
2938 let ptr = self.value.values;
2939 let len = self.len as isize;
2940 let mut i = 0;
2941 while i < len {
2942 let value = ptr.offset(i).read();
2943 array.push_back(txn, value);
2944 i += 1;
2945 }
2946 }
2947 Y_TEXT => {
2948 let text = TextRef::from(inner_ref);
2949 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2950 text.push(txn, init);
2951 }
2952 Y_XML_TEXT => {
2953 let text = XmlTextRef::from(inner_ref);
2954 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2955 text.push(txn, init);
2956 }
2957 _ => { }
2958 }
2959 }
2960 }
2961}
2962
2963#[repr(C)]
2969pub struct YOutput {
2970 pub tag: i8,
2988
2989 pub len: u32,
2997
2998 value: YOutputContent,
3000}
3001
3002impl YOutput {
3003 #[inline]
3004 unsafe fn null() -> YOutput {
3005 YOutput {
3006 tag: Y_JSON_NULL,
3007 len: 0,
3008 value: MaybeUninit::uninit().assume_init(),
3009 }
3010 }
3011
3012 #[inline]
3013 unsafe fn undefined() -> YOutput {
3014 YOutput {
3015 tag: Y_JSON_UNDEF,
3016 len: 0,
3017 value: MaybeUninit::uninit().assume_init(),
3018 }
3019 }
3020}
3021
3022impl std::fmt::Display for YOutput {
3023 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3024 let tag = self.tag;
3025 unsafe {
3026 if tag == Y_JSON_INT {
3027 write!(f, "{}", self.value.integer)
3028 } else if tag == Y_JSON_NUM {
3029 write!(f, "{}", self.value.num)
3030 } else if tag == Y_JSON_BOOL {
3031 write!(
3032 f,
3033 "{}",
3034 if self.value.flag == 0 {
3035 "false"
3036 } else {
3037 "true"
3038 }
3039 )
3040 } else if tag == Y_JSON_UNDEF {
3041 write!(f, "undefined")
3042 } else if tag == Y_JSON_NULL {
3043 write!(f, "null")
3044 } else if tag == Y_JSON_STR {
3045 write!(f, "{}", CString::from_raw(self.value.str).to_str().unwrap())
3046 } else if tag == Y_MAP {
3047 write!(f, "YMap")
3048 } else if tag == Y_ARRAY {
3049 write!(f, "YArray")
3050 } else if tag == Y_JSON_ARR {
3051 write!(f, "[")?;
3052 let slice = std::slice::from_raw_parts(self.value.array, self.len as usize);
3053 for o in slice {
3054 write!(f, ", {}", o)?;
3055 }
3056 write!(f, "]")
3057 } else if tag == Y_JSON_MAP {
3058 write!(f, "{{")?;
3059 let slice = std::slice::from_raw_parts(self.value.map, self.len as usize);
3060 for e in slice {
3061 let key = CStr::from_ptr(e.key).to_str().unwrap();
3062 let value = e.value.as_ref().unwrap();
3063 write!(f, ", '{}' => {}", key, value)?;
3064 }
3065 write!(f, "}}")
3066 } else if tag == Y_TEXT {
3067 write!(f, "YText")
3068 } else if tag == Y_XML_TEXT {
3069 write!(f, "YXmlText")
3070 } else if tag == Y_XML_ELEM {
3071 write!(f, "YXmlElement",)
3072 } else if tag == Y_JSON_BUF {
3073 write!(f, "YBinary(len: {})", self.len)
3074 } else {
3075 Ok(())
3076 }
3077 }
3078 }
3079}
3080
3081impl Drop for YOutput {
3082 fn drop(&mut self) {
3083 let tag = self.tag;
3084 unsafe {
3085 match tag {
3086 Y_JSON_STR => drop(CString::from_raw(self.value.str)),
3087 Y_JSON_ARR => drop(Vec::from_raw_parts(
3088 self.value.array,
3089 self.len as usize,
3090 self.len as usize,
3091 )),
3092 Y_JSON_MAP => drop(Vec::from_raw_parts(
3093 self.value.map,
3094 self.len as usize,
3095 self.len as usize,
3096 )),
3097 Y_JSON_BUF => drop(Vec::from_raw_parts(
3098 self.value.buf as *mut u8,
3100 self.len as usize,
3101 self.len as usize,
3102 )),
3103 Y_DOC => drop(Box::from_raw(self.value.y_doc)),
3104 _ => { }
3105 }
3106 }
3107 }
3108}
3109
3110impl From<Out> for YOutput {
3111 fn from(v: Out) -> Self {
3112 match v {
3113 Out::Any(v) => Self::from(v),
3114 Out::YText(v) => Self::from(v),
3115 Out::YArray(v) => Self::from(v),
3116 Out::YMap(v) => Self::from(v),
3117 Out::YXmlElement(v) => Self::from(v),
3118 Out::YXmlFragment(v) => Self::from(v),
3119 Out::YXmlText(v) => Self::from(v),
3120 Out::YDoc(v) => Self::from(v),
3121 Out::YWeakLink(v) => Self::from(v),
3122 Out::UndefinedRef(v) => Self::from(v),
3123 }
3124 }
3125}
3126
3127impl From<bool> for YOutput {
3128 #[inline]
3129 fn from(value: bool) -> Self {
3130 YOutput {
3131 tag: Y_JSON_BOOL,
3132 len: 1,
3133 value: YOutputContent {
3134 flag: if value { Y_TRUE } else { Y_FALSE },
3135 },
3136 }
3137 }
3138}
3139
3140impl From<f64> for YOutput {
3141 #[inline]
3142 fn from(value: f64) -> Self {
3143 YOutput {
3144 tag: Y_JSON_NUM,
3145 len: 1,
3146 value: YOutputContent { num: value },
3147 }
3148 }
3149}
3150
3151impl From<Number> for YOutput {
3152 #[inline]
3153 fn from(value: Number) -> Self {
3154 match value {
3155 Number::Int(value) => YOutput::from(value),
3156 Number::Float(value) => YOutput::from(value),
3157 }
3158 }
3159}
3160
3161impl From<i64> for YOutput {
3162 #[inline]
3163 fn from(value: i64) -> Self {
3164 YOutput {
3165 tag: Y_JSON_INT,
3166 len: 1,
3167 value: YOutputContent { integer: value },
3168 }
3169 }
3170}
3171
3172impl<'a> From<&'a str> for YOutput {
3173 fn from(value: &'a str) -> Self {
3174 YOutput {
3175 tag: Y_JSON_STR,
3176 len: value.len() as u32,
3177 value: YOutputContent {
3178 str: CString::new(value).unwrap().into_raw(),
3179 },
3180 }
3181 }
3182}
3183
3184impl<'a> From<&'a [u8]> for YOutput {
3185 fn from(value: &'a [u8]) -> Self {
3186 let value: Box<[u8]> = value.into();
3187 YOutput {
3188 tag: Y_JSON_BUF,
3189 len: value.len() as u32,
3190 value: YOutputContent {
3191 buf: Box::into_raw(value) as *const u8 as *mut c_char,
3192 },
3193 }
3194 }
3195}
3196
3197impl<'a> From<&'a [Any]> for YOutput {
3198 fn from(values: &'a [Any]) -> Self {
3199 let len = values.len() as u32;
3200 let mut array = Vec::with_capacity(values.len());
3201 for v in values.iter() {
3202 let output = YOutput::from(v);
3203 array.push(output);
3204 }
3205 let ptr = array.as_mut_ptr();
3206 forget(array);
3207 YOutput {
3208 tag: Y_JSON_ARR,
3209 len,
3210 value: YOutputContent { array: ptr },
3211 }
3212 }
3213}
3214
3215impl<'a> From<&'a HashMap<String, Any>> for YOutput {
3216 fn from(value: &'a HashMap<String, Any>) -> Self {
3217 let len = value.len() as u32;
3218 let mut array = Vec::with_capacity(len as usize);
3219 for (k, v) in value.iter() {
3220 let entry = YMapEntry::new(k.as_str(), Box::new(YOutput::from(v)));
3221 array.push(entry);
3222 }
3223 let ptr = array.as_mut_ptr();
3224 forget(array);
3225 YOutput {
3226 tag: Y_JSON_MAP,
3227 len,
3228 value: YOutputContent { map: ptr },
3229 }
3230 }
3231}
3232
3233impl<'a> From<&'a Any> for YOutput {
3234 fn from(v: &'a Any) -> Self {
3235 unsafe {
3236 match v {
3237 Any::Null => YOutput::null(),
3238 Any::Undefined => YOutput::undefined(),
3239 Any::Bool(v) => YOutput::from(*v),
3240 Any::Number(v) => YOutput::from(*v),
3241 Any::String(v) => YOutput::from(v.as_ref()),
3242 Any::Buffer(v) => YOutput::from(v.as_ref()),
3243 Any::Array(v) => YOutput::from(v.as_ref()),
3244 Any::Map(v) => YOutput::from(v.as_ref()),
3245 }
3246 }
3247 }
3248}
3249
3250impl From<Any> for YOutput {
3251 fn from(v: Any) -> Self {
3252 unsafe {
3253 match v {
3254 Any::Null => YOutput::null(),
3255 Any::Undefined => YOutput::undefined(),
3256 Any::Bool(v) => YOutput::from(v),
3257 Any::Number(v) => YOutput::from(v),
3258 Any::String(v) => YOutput::from(v.as_ref()),
3259 Any::Buffer(v) => YOutput::from(v.as_ref()),
3260 Any::Array(v) => YOutput::from(v.as_ref()),
3261 Any::Map(v) => YOutput::from(v.as_ref()),
3262 }
3263 }
3264 }
3265}
3266
3267impl From<TextRef> for YOutput {
3268 fn from(v: TextRef) -> Self {
3269 YOutput {
3270 tag: Y_TEXT,
3271 len: 1,
3272 value: YOutputContent {
3273 y_type: v.into_raw_branch(),
3274 },
3275 }
3276 }
3277}
3278
3279impl From<ArrayRef> for YOutput {
3280 fn from(v: ArrayRef) -> Self {
3281 YOutput {
3282 tag: Y_ARRAY,
3283 len: 1,
3284 value: YOutputContent {
3285 y_type: v.into_raw_branch(),
3286 },
3287 }
3288 }
3289}
3290
3291impl From<WeakRef<BranchPtr>> for YOutput {
3292 fn from(v: WeakRef<BranchPtr>) -> Self {
3293 YOutput {
3294 tag: Y_WEAK_LINK,
3295 len: 1,
3296 value: YOutputContent {
3297 y_type: v.into_raw_branch(),
3298 },
3299 }
3300 }
3301}
3302
3303impl From<MapRef> for YOutput {
3304 fn from(v: MapRef) -> Self {
3305 YOutput {
3306 tag: Y_MAP,
3307 len: 1,
3308 value: YOutputContent {
3309 y_type: v.into_raw_branch(),
3310 },
3311 }
3312 }
3313}
3314
3315impl From<BranchPtr> for YOutput {
3316 fn from(v: BranchPtr) -> Self {
3317 let branch_ref = v.as_ref();
3318 YOutput {
3319 tag: Y_UNDEFINED,
3320 len: 1,
3321 value: YOutputContent {
3322 y_type: branch_ref as *const Branch as *mut Branch,
3323 },
3324 }
3325 }
3326}
3327
3328impl From<XmlElementRef> for YOutput {
3329 fn from(v: XmlElementRef) -> Self {
3330 YOutput {
3331 tag: Y_XML_ELEM,
3332 len: 1,
3333 value: YOutputContent {
3334 y_type: v.into_raw_branch(),
3335 },
3336 }
3337 }
3338}
3339
3340impl From<XmlTextRef> for YOutput {
3341 fn from(v: XmlTextRef) -> Self {
3342 YOutput {
3343 tag: Y_XML_TEXT,
3344 len: 1,
3345 value: YOutputContent {
3346 y_type: v.into_raw_branch(),
3347 },
3348 }
3349 }
3350}
3351
3352impl From<XmlFragmentRef> for YOutput {
3353 fn from(v: XmlFragmentRef) -> Self {
3354 YOutput {
3355 tag: Y_XML_FRAG,
3356 len: 1,
3357 value: YOutputContent {
3358 y_type: v.into_raw_branch(),
3359 },
3360 }
3361 }
3362}
3363
3364impl From<Doc> for YOutput {
3365 fn from(v: Doc) -> Self {
3366 YOutput {
3367 tag: Y_DOC,
3368 len: 1,
3369 value: YOutputContent {
3370 y_doc: Box::into_raw(Box::new(v.clone())),
3371 },
3372 }
3373 }
3374}
3375
3376#[repr(C)]
3377union YOutputContent {
3378 flag: u8,
3379 num: f64,
3380 integer: i64,
3381 str: *mut c_char,
3382 buf: *const c_char,
3383 array: *mut YOutput,
3384 map: *mut YMapEntry,
3385 y_type: *mut Branch,
3386 y_doc: *mut Doc,
3387}
3388
3389#[no_mangle]
3391pub unsafe extern "C" fn youtput_destroy(val: *mut YOutput) {
3392 if !val.is_null() {
3393 drop(Box::from_raw(val))
3394 }
3395}
3396
3397#[no_mangle]
3400pub unsafe extern "C" fn yinput_null() -> YInput {
3401 YInput {
3402 tag: Y_JSON_NULL,
3403 len: 0,
3404 value: MaybeUninit::uninit().assume_init(),
3405 }
3406}
3407
3408#[no_mangle]
3411pub unsafe extern "C" fn yinput_undefined() -> YInput {
3412 YInput {
3413 tag: Y_JSON_UNDEF,
3414 len: 0,
3415 value: MaybeUninit::uninit().assume_init(),
3416 }
3417}
3418
3419#[no_mangle]
3422pub unsafe extern "C" fn yinput_bool(flag: u8) -> YInput {
3423 YInput {
3424 tag: Y_JSON_BOOL,
3425 len: 1,
3426 value: YInputContent { flag },
3427 }
3428}
3429
3430#[no_mangle]
3433pub unsafe extern "C" fn yinput_float(num: f64) -> YInput {
3434 YInput {
3435 tag: Y_JSON_NUM,
3436 len: 1,
3437 value: YInputContent { num },
3438 }
3439}
3440
3441#[no_mangle]
3444pub unsafe extern "C" fn yinput_long(integer: i64) -> YInput {
3445 YInput {
3446 tag: Y_JSON_INT,
3447 len: 1,
3448 value: YInputContent { integer },
3449 }
3450}
3451
3452#[no_mangle]
3457pub unsafe extern "C" fn yinput_string(str: *const c_char) -> YInput {
3458 YInput {
3459 tag: Y_JSON_STR,
3460 len: 1,
3461 value: YInputContent {
3462 str: str as *mut c_char,
3463 },
3464 }
3465}
3466
3467#[no_mangle]
3473pub unsafe extern "C" fn yinput_json(str: *const c_char) -> YInput {
3474 YInput {
3475 tag: Y_JSON,
3476 len: 1,
3477 value: YInputContent {
3478 str: str as *mut c_char,
3479 },
3480 }
3481}
3482
3483#[no_mangle]
3487pub unsafe extern "C" fn yinput_binary(buf: *const c_char, len: u32) -> YInput {
3488 YInput {
3489 tag: Y_JSON_BUF,
3490 len,
3491 value: YInputContent {
3492 buf: buf as *mut c_char,
3493 },
3494 }
3495}
3496
3497#[no_mangle]
3501pub unsafe extern "C" fn yinput_json_array(values: *mut YInput, len: u32) -> YInput {
3502 YInput {
3503 tag: Y_JSON_ARR,
3504 len,
3505 value: YInputContent { values },
3506 }
3507}
3508
3509#[no_mangle]
3516pub unsafe extern "C" fn yinput_json_map(
3517 keys: *mut *mut c_char,
3518 values: *mut YInput,
3519 len: u32,
3520) -> YInput {
3521 YInput {
3522 tag: Y_JSON_MAP,
3523 len,
3524 value: YInputContent {
3525 map: ManuallyDrop::new(YMapInputData { keys, values }),
3526 },
3527 }
3528}
3529
3530#[no_mangle]
3535pub unsafe extern "C" fn yinput_yarray(values: *mut YInput, len: u32) -> YInput {
3536 YInput {
3537 tag: Y_ARRAY,
3538 len,
3539 value: YInputContent { values },
3540 }
3541}
3542
3543#[no_mangle]
3550pub unsafe extern "C" fn yinput_ymap(
3551 keys: *mut *mut c_char,
3552 values: *mut YInput,
3553 len: u32,
3554) -> YInput {
3555 YInput {
3556 tag: Y_MAP,
3557 len,
3558 value: YInputContent {
3559 map: ManuallyDrop::new(YMapInputData { keys, values }),
3560 },
3561 }
3562}
3563
3564#[no_mangle]
3570pub unsafe extern "C" fn yinput_ytext(str: *mut c_char) -> YInput {
3571 YInput {
3572 tag: Y_TEXT,
3573 len: 1,
3574 value: YInputContent { str },
3575 }
3576}
3577
3578#[no_mangle]
3584pub unsafe extern "C" fn yinput_yxmlelem(name: *mut c_char) -> YInput {
3585 YInput {
3586 tag: Y_XML_ELEM,
3587 len: 1,
3588 value: YInputContent { str: name },
3589 }
3590}
3591
3592#[no_mangle]
3598pub unsafe extern "C" fn yinput_yxmltext(str: *mut c_char) -> YInput {
3599 YInput {
3600 tag: Y_XML_TEXT,
3601 len: 1,
3602 value: YInputContent { str },
3603 }
3604}
3605
3606#[no_mangle]
3611pub unsafe extern "C" fn yinput_ydoc(doc: *mut Doc) -> YInput {
3612 YInput {
3613 tag: Y_DOC,
3614 len: 1,
3615 value: YInputContent { doc },
3616 }
3617}
3618
3619#[no_mangle]
3622pub unsafe extern "C" fn yinput_weak(weak: *const Weak) -> YInput {
3623 YInput {
3624 tag: Y_WEAK_LINK,
3625 len: 1,
3626 value: YInputContent { weak },
3627 }
3628}
3629
3630#[no_mangle]
3633pub unsafe extern "C" fn youtput_read_ydoc(val: *const YOutput) -> *mut Doc {
3634 let v = val.as_ref().unwrap();
3635 if v.tag == Y_DOC {
3636 v.value.y_doc
3637 } else {
3638 std::ptr::null_mut()
3639 }
3640}
3641
3642#[no_mangle]
3646pub unsafe extern "C" fn youtput_read_bool(val: *const YOutput) -> *const u8 {
3647 let v = val.as_ref().unwrap();
3648 if v.tag == Y_JSON_BOOL {
3649 &v.value.flag
3650 } else {
3651 std::ptr::null()
3652 }
3653}
3654
3655#[no_mangle]
3660pub unsafe extern "C" fn youtput_read_float(val: *const YOutput) -> *const f64 {
3661 let v = val.as_ref().unwrap();
3662 if v.tag == Y_JSON_NUM {
3663 &v.value.num
3664 } else {
3665 std::ptr::null()
3666 }
3667}
3668
3669#[no_mangle]
3674pub unsafe extern "C" fn youtput_read_long(val: *const YOutput) -> *const i64 {
3675 let v = val.as_ref().unwrap();
3676 if v.tag == Y_JSON_INT {
3677 &v.value.integer
3678 } else {
3679 std::ptr::null()
3680 }
3681}
3682
3683#[no_mangle]
3690pub unsafe extern "C" fn youtput_read_string(val: *const YOutput) -> *mut c_char {
3691 let v = val.as_ref().unwrap();
3692 if v.tag == Y_JSON_STR {
3693 v.value.str
3694 } else {
3695 std::ptr::null_mut()
3696 }
3697}
3698
3699#[no_mangle]
3706pub unsafe extern "C" fn youtput_read_binary(val: *const YOutput) -> *const c_char {
3707 let v = val.as_ref().unwrap();
3708 if v.tag == Y_JSON_BUF {
3709 v.value.buf
3710 } else {
3711 std::ptr::null()
3712 }
3713}
3714
3715#[no_mangle]
3722pub unsafe extern "C" fn youtput_read_json_array(val: *const YOutput) -> *mut YOutput {
3723 let v = val.as_ref().unwrap();
3724 if v.tag == Y_JSON_ARR {
3725 v.value.array
3726 } else {
3727 std::ptr::null_mut()
3728 }
3729}
3730
3731#[no_mangle]
3738pub unsafe extern "C" fn youtput_read_json_map(val: *const YOutput) -> *mut YMapEntry {
3739 let v = val.as_ref().unwrap();
3740 if v.tag == Y_JSON_MAP {
3741 v.value.map
3742 } else {
3743 std::ptr::null_mut()
3744 }
3745}
3746
3747#[no_mangle]
3753pub unsafe extern "C" fn youtput_read_yarray(val: *const YOutput) -> *mut Branch {
3754 let v = val.as_ref().unwrap();
3755 if v.tag == Y_ARRAY {
3756 v.value.y_type
3757 } else {
3758 std::ptr::null_mut()
3759 }
3760}
3761
3762#[no_mangle]
3768pub unsafe extern "C" fn youtput_read_yxmlelem(val: *const YOutput) -> *mut Branch {
3769 let v = val.as_ref().unwrap();
3770 if v.tag == Y_XML_ELEM {
3771 v.value.y_type
3772 } else {
3773 std::ptr::null_mut()
3774 }
3775}
3776
3777#[no_mangle]
3783pub unsafe extern "C" fn youtput_read_ymap(val: *const YOutput) -> *mut Branch {
3784 let v = val.as_ref().unwrap();
3785 if v.tag == Y_MAP {
3786 v.value.y_type
3787 } else {
3788 std::ptr::null_mut()
3789 }
3790}
3791
3792#[no_mangle]
3798pub unsafe extern "C" fn youtput_read_ytext(val: *const YOutput) -> *mut Branch {
3799 let v = val.as_ref().unwrap();
3800 if v.tag == Y_TEXT {
3801 v.value.y_type
3802 } else {
3803 std::ptr::null_mut()
3804 }
3805}
3806
3807#[no_mangle]
3813pub unsafe extern "C" fn youtput_read_yxmltext(val: *const YOutput) -> *mut Branch {
3814 let v = val.as_ref().unwrap();
3815 if v.tag == Y_XML_TEXT {
3816 v.value.y_type
3817 } else {
3818 std::ptr::null_mut()
3819 }
3820}
3821
3822#[no_mangle]
3828pub unsafe extern "C" fn youtput_read_yweak(val: *const YOutput) -> *mut Branch {
3829 let v = val.as_ref().unwrap();
3830 if v.tag == Y_WEAK_LINK {
3831 v.value.y_type
3832 } else {
3833 std::ptr::null_mut()
3834 }
3835}
3836
3837#[no_mangle]
3840pub unsafe extern "C" fn yunobserve(branch: *const Branch, key_len: u32, key: *const c_char) -> u8 {
3841 assert!(!branch.is_null());
3842 let key = origin(key_len, key);
3843 let branch = (branch as *mut Branch).as_mut().unwrap();
3844 branch.unobserve(&key) as u8
3845}
3846
3847#[no_mangle]
3850pub unsafe extern "C" fn yunobserve_deep(
3851 branch: *const Branch,
3852 key_len: u32,
3853 key: *const c_char,
3854) -> u8 {
3855 assert!(!branch.is_null());
3856 let key = origin(key_len, key);
3857 let branch = (branch as *mut Branch).as_mut().unwrap();
3858 branch.unobserve_deep(&key) as u8
3859}
3860
3861#[no_mangle]
3865pub unsafe extern "C" fn ytext_observe(
3866 txt: *const Branch,
3867 key_len: u32,
3868 key: *const c_char,
3869 state: *mut c_void,
3870 cb: extern "C" fn(*mut c_void, *const YTextEvent),
3871) {
3872 assert!(!txt.is_null());
3873 let state = CallbackState::new(state);
3874
3875 let txt = TextRef::from_raw_branch(txt);
3876 txt.observe(origin(key_len, key), move |txn, e| {
3877 let e = YTextEvent::new(e, txn);
3878 cb(state.0, &e as *const YTextEvent);
3879 });
3880}
3881
3882#[no_mangle]
3886pub unsafe extern "C" fn ymap_observe(
3887 map: *const Branch,
3888 key_len: u32,
3889 key: *const c_char,
3890 state: *mut c_void,
3891 cb: extern "C" fn(*mut c_void, *const YMapEvent),
3892) {
3893 assert!(!map.is_null());
3894 let state = CallbackState::new(state);
3895
3896 let map = MapRef::from_raw_branch(map);
3897 map.observe(origin(key_len, key), move |txn, e| {
3898 let e = YMapEvent::new(e, txn);
3899 cb(state.0, &e as *const YMapEvent);
3900 });
3901}
3902
3903#[no_mangle]
3907pub unsafe extern "C" fn yarray_observe(
3908 array: *const Branch,
3909 key_len: u32,
3910 key: *const c_char,
3911 state: *mut c_void,
3912 cb: extern "C" fn(*mut c_void, *const YArrayEvent),
3913) {
3914 assert!(!array.is_null());
3915 let state = CallbackState::new(state);
3916
3917 let array = ArrayRef::from_raw_branch(array);
3918 array.observe(origin(key_len, key), move |txn, e| {
3919 let e = YArrayEvent::new(e, txn);
3920 cb(state.0, &e as *const YArrayEvent);
3921 });
3922}
3923
3924#[no_mangle]
3928pub unsafe extern "C" fn yxmlelem_observe(
3929 xml: *const Branch,
3930 key_len: u32,
3931 key: *const c_char,
3932 state: *mut c_void,
3933 cb: extern "C" fn(*mut c_void, *const YXmlEvent),
3934) {
3935 assert!(!xml.is_null());
3936 let state = CallbackState::new(state);
3937
3938 let xml = XmlElementRef::from_raw_branch(xml);
3939 xml.observe(origin(key_len, key), move |txn, e| {
3940 let e = YXmlEvent::new(e, txn);
3941 cb(state.0, &e as *const YXmlEvent);
3942 });
3943}
3944
3945#[no_mangle]
3949pub unsafe extern "C" fn yxmltext_observe(
3950 xml: *const Branch,
3951 key_len: u32,
3952 key: *const c_char,
3953 state: *mut c_void,
3954 cb: extern "C" fn(*mut c_void, *const YXmlTextEvent),
3955) {
3956 assert!(!xml.is_null());
3957
3958 let state = CallbackState::new(state);
3959 let xml = XmlTextRef::from_raw_branch(xml);
3960 xml.observe(origin(key_len, key), move |txn, e| {
3961 let e = YXmlTextEvent::new(e, txn);
3962 cb(state.0, &e as *const YXmlTextEvent);
3963 });
3964}
3965
3966#[no_mangle]
3970pub unsafe extern "C" fn yobserve_deep(
3971 ytype: *mut Branch,
3972 key_len: u32,
3973 key: *const c_char,
3974 state: *mut c_void,
3975 cb: extern "C" fn(*mut c_void, u32, *const YEvent),
3976) {
3977 assert!(!ytype.is_null());
3978
3979 let state = CallbackState::new(state);
3980 let key = origin(key_len, key);
3981 let branch = ytype.as_mut().unwrap();
3982 branch.observe_deep(key, move |txn, events| {
3983 let events: Vec<_> = events.iter().map(|e| YEvent::new(txn, e)).collect();
3984 let len = events.len() as u32;
3985 cb(state.0, len, events.as_ptr());
3986 });
3987}
3988
3989#[repr(C)]
3992pub struct YAfterTransactionEvent {
3993 pub before_state: YStateVector,
3995 pub after_state: YStateVector,
3997 pub delete_set: YIdSet,
3999}
4000
4001impl YAfterTransactionEvent {
4002 unsafe fn new(e: &TransactionCleanupEvent) -> Self {
4003 YAfterTransactionEvent {
4004 before_state: YStateVector::new(&e.before_state),
4005 after_state: YStateVector::new(&e.after_state),
4006 delete_set: YIdSet::new(&e.delete_set),
4007 }
4008 }
4009}
4010
4011#[repr(C)]
4012pub struct YSubdocsEvent {
4013 added_len: u32,
4014 removed_len: u32,
4015 loaded_len: u32,
4016 added: *mut *mut Doc,
4017 removed: *mut *mut Doc,
4018 loaded: *mut *mut Doc,
4019}
4020
4021impl YSubdocsEvent {
4022 unsafe fn new(e: &SubdocsEvent) -> Self {
4023 fn into_ptr(v: SubdocsEventIter) -> *mut *mut Doc {
4024 let array: Vec<_> = v.map(|doc| Box::into_raw(Box::new(doc.clone()))).collect();
4025 let mut boxed = array.into_boxed_slice();
4026 let ptr = boxed.as_mut_ptr();
4027 forget(boxed);
4028 ptr
4029 }
4030
4031 let added = e.added();
4032 let removed = e.removed();
4033 let loaded = e.loaded();
4034
4035 YSubdocsEvent {
4036 added_len: added.len() as u32,
4037 removed_len: removed.len() as u32,
4038 loaded_len: loaded.len() as u32,
4039 added: into_ptr(added),
4040 removed: into_ptr(removed),
4041 loaded: into_ptr(loaded),
4042 }
4043 }
4044}
4045
4046impl Drop for YSubdocsEvent {
4047 fn drop(&mut self) {
4048 fn release(len: u32, buf: *mut *mut Doc) {
4049 unsafe {
4050 let docs = Vec::from_raw_parts(buf, len as usize, len as usize);
4051 for d in docs {
4052 drop(Box::from_raw(d));
4053 }
4054 }
4055 }
4056
4057 release(self.added_len, self.added);
4058 release(self.removed_len, self.removed);
4059 release(self.loaded_len, self.loaded);
4060 }
4061}
4062
4063#[repr(C)]
4066pub struct YStateVector {
4067 pub entries_count: u32,
4069 pub client_ids: *mut u64,
4073 pub clocks: *mut u32,
4077}
4078
4079impl YStateVector {
4080 unsafe fn new(sv: &StateVector) -> Self {
4081 let entries_count = sv.len() as u32;
4082 let mut client_ids = Vec::with_capacity(sv.len());
4083 let mut clocks = Vec::with_capacity(sv.len());
4084 for (&client, &clock) in sv.iter() {
4085 client_ids.push(client.get());
4086 clocks.push(clock as u32);
4087 }
4088
4089 YStateVector {
4090 entries_count,
4091 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
4092 clocks: Box::into_raw(clocks.into_boxed_slice()) as *mut _,
4093 }
4094 }
4095}
4096
4097impl Drop for YStateVector {
4098 fn drop(&mut self) {
4099 let len = self.entries_count as usize;
4100 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
4101 drop(unsafe { Vec::from_raw_parts(self.clocks, len, len) });
4102 }
4103}
4104
4105#[repr(C)]
4109pub struct YIdSet {
4110 pub entries_count: u32,
4112 pub client_ids: *mut u64,
4116 pub ranges: *mut YIdRangeSeq,
4120}
4121
4122impl YIdSet {
4123 unsafe fn new(ds: &IdSet) -> Self {
4124 let len = ds.len();
4125 let mut client_ids = Vec::with_capacity(len);
4126 let mut ranges = Vec::with_capacity(len);
4127
4128 for (&client, range) in ds.iter() {
4129 client_ids.push(client.get());
4130 let seq: Vec<_> = range
4131 .iter()
4132 .map(|r| YIdRange {
4133 start: r.start as u32,
4134 end: r.end as u32,
4135 })
4136 .collect();
4137 ranges.push(YIdRangeSeq {
4138 len: seq.len() as u32,
4139 seq: Box::into_raw(seq.into_boxed_slice()) as *mut _,
4140 })
4141 }
4142
4143 YIdSet {
4144 entries_count: len as u32,
4145 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
4146 ranges: Box::into_raw(ranges.into_boxed_slice()) as *mut _,
4147 }
4148 }
4149}
4150
4151impl Drop for YIdSet {
4152 fn drop(&mut self) {
4153 let len = self.entries_count as usize;
4154 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
4155 drop(unsafe { Vec::from_raw_parts(self.ranges, len, len) });
4156 }
4157}
4158
4159#[repr(C)]
4162pub struct YIdRangeSeq {
4163 pub len: u32,
4165 pub seq: *mut YIdRange,
4169}
4170
4171impl Drop for YIdRangeSeq {
4172 fn drop(&mut self) {
4173 let len = self.len as usize;
4174 drop(unsafe { Vec::from_raw_parts(self.seq, len, len) })
4175 }
4176}
4177
4178#[repr(C)]
4179pub struct YIdRange {
4180 pub start: u32,
4181 pub end: u32,
4182}
4183
4184#[repr(C)]
4185pub struct YEvent {
4186 pub tag: i8,
4194
4195 pub content: YEventContent,
4198}
4199
4200impl YEvent {
4201 fn new<'doc>(txn: &yrs::TransactionMut<'doc>, e: &Event) -> YEvent {
4202 match e {
4203 Event::Text(e) => YEvent {
4204 tag: Y_TEXT,
4205 content: YEventContent {
4206 text: YTextEvent::new(e, txn),
4207 },
4208 },
4209 Event::Array(e) => YEvent {
4210 tag: Y_ARRAY,
4211 content: YEventContent {
4212 array: YArrayEvent::new(e, txn),
4213 },
4214 },
4215 Event::Map(e) => YEvent {
4216 tag: Y_MAP,
4217 content: YEventContent {
4218 map: YMapEvent::new(e, txn),
4219 },
4220 },
4221 Event::XmlFragment(e) => YEvent {
4222 tag: if let XmlOut::Fragment(_) = e.target() {
4223 Y_XML_FRAG
4224 } else {
4225 Y_XML_ELEM
4226 },
4227 content: YEventContent {
4228 xml_elem: YXmlEvent::new(e, txn),
4229 },
4230 },
4231 Event::XmlText(e) => YEvent {
4232 tag: Y_XML_TEXT,
4233 content: YEventContent {
4234 xml_text: YXmlTextEvent::new(e, txn),
4235 },
4236 },
4237 Event::Weak(e) => YEvent {
4238 tag: Y_WEAK_LINK,
4239 content: YEventContent {
4240 weak: YWeakLinkEvent::new(e, txn),
4241 },
4242 },
4243 }
4244 }
4245}
4246
4247#[repr(C)]
4248pub union YEventContent {
4249 pub text: YTextEvent,
4250 pub map: YMapEvent,
4251 pub array: YArrayEvent,
4252 pub xml_elem: YXmlEvent,
4253 pub xml_text: YXmlTextEvent,
4254 pub weak: YWeakLinkEvent,
4255}
4256
4257#[repr(C)]
4261#[derive(Copy, Clone)]
4262pub struct YTextEvent {
4263 inner: *const c_void,
4264 txn: *const yrs::TransactionMut<'static>,
4265}
4266
4267impl YTextEvent {
4268 fn new<'dev>(inner: &TextEvent, txn: &yrs::TransactionMut<'dev>) -> Self {
4269 let inner = inner as *const TextEvent as *const _;
4270 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4271 let txn = txn as *const _;
4272 YTextEvent { inner, txn }
4273 }
4274
4275 fn txn(&self) -> &yrs::TransactionMut {
4276 unsafe { self.txn.as_ref().unwrap() }
4277 }
4278}
4279
4280impl Deref for YTextEvent {
4281 type Target = TextEvent;
4282
4283 fn deref(&self) -> &Self::Target {
4284 unsafe { (self.inner as *const TextEvent).as_ref().unwrap() }
4285 }
4286}
4287
4288#[repr(C)]
4292#[derive(Copy, Clone)]
4293pub struct YArrayEvent {
4294 inner: *const c_void,
4295 txn: *const yrs::TransactionMut<'static>,
4296}
4297
4298impl YArrayEvent {
4299 fn new<'doc>(inner: &ArrayEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4300 let inner = inner as *const ArrayEvent as *const _;
4301 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4302 let txn = txn as *const _;
4303 YArrayEvent { inner, txn }
4304 }
4305
4306 fn txn(&self) -> &yrs::TransactionMut {
4307 unsafe { self.txn.as_ref().unwrap() }
4308 }
4309}
4310
4311impl Deref for YArrayEvent {
4312 type Target = ArrayEvent;
4313
4314 fn deref(&self) -> &Self::Target {
4315 unsafe { (self.inner as *const ArrayEvent).as_ref().unwrap() }
4316 }
4317}
4318
4319#[repr(C)]
4323#[derive(Copy, Clone)]
4324pub struct YMapEvent {
4325 inner: *const c_void,
4326 txn: *const yrs::TransactionMut<'static>,
4327}
4328
4329impl YMapEvent {
4330 fn new<'doc>(inner: &MapEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4331 let inner = inner as *const MapEvent as *const _;
4332 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4333 let txn = txn as *const _;
4334 YMapEvent { inner, txn }
4335 }
4336
4337 fn txn(&self) -> &yrs::TransactionMut<'static> {
4338 unsafe { self.txn.as_ref().unwrap() }
4339 }
4340}
4341
4342impl Deref for YMapEvent {
4343 type Target = MapEvent;
4344
4345 fn deref(&self) -> &Self::Target {
4346 unsafe { (self.inner as *const MapEvent).as_ref().unwrap() }
4347 }
4348}
4349
4350#[repr(C)]
4355#[derive(Copy, Clone)]
4356pub struct YXmlEvent {
4357 inner: *const c_void,
4358 txn: *const yrs::TransactionMut<'static>,
4359}
4360
4361impl YXmlEvent {
4362 fn new<'doc>(inner: &XmlEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4363 let inner = inner as *const XmlEvent as *const _;
4364 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4365 let txn = txn as *const _;
4366 YXmlEvent { inner, txn }
4367 }
4368
4369 fn txn(&self) -> &yrs::TransactionMut<'static> {
4370 unsafe { self.txn.as_ref().unwrap() }
4371 }
4372}
4373
4374impl Deref for YXmlEvent {
4375 type Target = XmlEvent;
4376
4377 fn deref(&self) -> &Self::Target {
4378 unsafe { (self.inner as *const XmlEvent).as_ref().unwrap() }
4379 }
4380}
4381
4382#[repr(C)]
4387#[derive(Copy, Clone)]
4388pub struct YXmlTextEvent {
4389 inner: *const c_void,
4390 txn: *const yrs::TransactionMut<'static>,
4391}
4392
4393impl YXmlTextEvent {
4394 fn new<'doc>(inner: &XmlTextEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4395 let inner = inner as *const XmlTextEvent as *const _;
4396 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4397 let txn = txn as *const _;
4398 YXmlTextEvent { inner, txn }
4399 }
4400
4401 fn txn(&self) -> &yrs::TransactionMut<'static> {
4402 unsafe { self.txn.as_ref().unwrap() }
4403 }
4404}
4405
4406impl Deref for YXmlTextEvent {
4407 type Target = XmlTextEvent;
4408
4409 fn deref(&self) -> &Self::Target {
4410 unsafe { (self.inner as *const XmlTextEvent).as_ref().unwrap() }
4411 }
4412}
4413
4414#[repr(C)]
4417#[derive(Copy, Clone)]
4418pub struct YWeakLinkEvent {
4419 inner: *const c_void,
4420 txn: *const yrs::TransactionMut<'static>,
4421}
4422
4423impl YWeakLinkEvent {
4424 fn new<'doc>(inner: &WeakEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4425 let inner = inner as *const WeakEvent as *const _;
4426 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4427 let txn = txn as *const _;
4428 YWeakLinkEvent { inner, txn }
4429 }
4430}
4431
4432impl Deref for YWeakLinkEvent {
4433 type Target = WeakEvent;
4434
4435 fn deref(&self) -> &Self::Target {
4436 unsafe { (self.inner as *const WeakEvent).as_ref().unwrap() }
4437 }
4438}
4439
4440#[no_mangle]
4442pub unsafe extern "C" fn ytext_event_target(e: *const YTextEvent) -> *mut Branch {
4443 assert!(!e.is_null());
4444 let out = (&*e).target().clone();
4445 out.into_raw_branch()
4446}
4447
4448#[no_mangle]
4450pub unsafe extern "C" fn yarray_event_target(e: *const YArrayEvent) -> *mut Branch {
4451 assert!(!e.is_null());
4452 let out = (&*e).target().clone();
4453 out.into_raw_branch()
4454}
4455
4456#[no_mangle]
4458pub unsafe extern "C" fn ymap_event_target(e: *const YMapEvent) -> *mut Branch {
4459 assert!(!e.is_null());
4460 let out = (&*e).target().clone();
4461 out.into_raw_branch()
4462}
4463
4464#[no_mangle]
4466pub unsafe extern "C" fn yxmlelem_event_target(e: *const YXmlEvent) -> *mut Branch {
4467 assert!(!e.is_null());
4468 let out = (&*e).target().clone();
4469 match out {
4470 XmlOut::Element(e) => e.into_raw_branch(),
4471 XmlOut::Fragment(e) => e.into_raw_branch(),
4472 XmlOut::Text(e) => e.into_raw_branch(),
4473 }
4474}
4475
4476#[no_mangle]
4478pub unsafe extern "C" fn yxmltext_event_target(e: *const YXmlTextEvent) -> *mut Branch {
4479 assert!(!e.is_null());
4480 let out = (&*e).target().clone();
4481 out.into_raw_branch()
4482}
4483
4484#[no_mangle]
4491pub unsafe extern "C" fn ytext_event_path(
4492 e: *const YTextEvent,
4493 len: *mut u32,
4494) -> *mut YPathSegment {
4495 assert!(!e.is_null());
4496 let e = &*e;
4497 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4498 let out = path.into_boxed_slice();
4499 *len = out.len() as u32;
4500 Box::into_raw(out) as *mut _
4501}
4502
4503#[no_mangle]
4510pub unsafe extern "C" fn ymap_event_path(e: *const YMapEvent, len: *mut u32) -> *mut YPathSegment {
4511 assert!(!e.is_null());
4512 let e = &*e;
4513 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4514 let out = path.into_boxed_slice();
4515 *len = out.len() as u32;
4516 Box::into_raw(out) as *mut _
4517}
4518
4519#[no_mangle]
4526pub unsafe extern "C" fn yxmlelem_event_path(
4527 e: *const YXmlEvent,
4528 len: *mut u32,
4529) -> *mut YPathSegment {
4530 assert!(!e.is_null());
4531 let e = &*e;
4532 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4533 let out = path.into_boxed_slice();
4534 *len = out.len() as u32;
4535 Box::into_raw(out) as *mut _
4536}
4537
4538#[no_mangle]
4545pub unsafe extern "C" fn yxmltext_event_path(
4546 e: *const YXmlTextEvent,
4547 len: *mut u32,
4548) -> *mut YPathSegment {
4549 assert!(!e.is_null());
4550 let e = &*e;
4551 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4552 let out = path.into_boxed_slice();
4553 *len = out.len() as u32;
4554 Box::into_raw(out) as *mut _
4555}
4556
4557#[no_mangle]
4564pub unsafe extern "C" fn yarray_event_path(
4565 e: *const YArrayEvent,
4566 len: *mut u32,
4567) -> *mut YPathSegment {
4568 assert!(!e.is_null());
4569 let e = &*e;
4570 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4571 let out = path.into_boxed_slice();
4572 *len = out.len() as u32;
4573 Box::into_raw(out) as *mut _
4574}
4575
4576#[no_mangle]
4579pub unsafe extern "C" fn ypath_destroy(path: *mut YPathSegment, len: u32) {
4580 if !path.is_null() {
4581 drop(Vec::from_raw_parts(path, len as usize, len as usize));
4582 }
4583}
4584
4585#[no_mangle]
4592pub unsafe extern "C" fn ytext_event_delta(e: *const YTextEvent, len: *mut u32) -> *mut YDeltaOut {
4593 assert!(!e.is_null());
4594 let e = &*e;
4595 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4596
4597 let out = delta.into_boxed_slice();
4598 *len = out.len() as u32;
4599 Box::into_raw(out) as *mut _
4600}
4601
4602#[no_mangle]
4609pub unsafe extern "C" fn yxmltext_event_delta(
4610 e: *const YXmlTextEvent,
4611 len: *mut u32,
4612) -> *mut YDeltaOut {
4613 assert!(!e.is_null());
4614 let e = &*e;
4615 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4616
4617 let out = delta.into_boxed_slice();
4618 *len = out.len() as u32;
4619 Box::into_raw(out) as *mut _
4620}
4621
4622#[no_mangle]
4629pub unsafe extern "C" fn yarray_event_delta(
4630 e: *const YArrayEvent,
4631 len: *mut u32,
4632) -> *mut YEventChange {
4633 assert!(!e.is_null());
4634 let e = &*e;
4635 let delta: Vec<_> = e
4636 .delta(e.txn())
4637 .into_iter()
4638 .map(YEventChange::from)
4639 .collect();
4640
4641 let out = delta.into_boxed_slice();
4642 *len = out.len() as u32;
4643 Box::into_raw(out) as *mut _
4644}
4645
4646#[no_mangle]
4653pub unsafe extern "C" fn yxmlelem_event_delta(
4654 e: *const YXmlEvent,
4655 len: *mut u32,
4656) -> *mut YEventChange {
4657 assert!(!e.is_null());
4658 let e = &*e;
4659 let delta: Vec<_> = e
4660 .delta(e.txn())
4661 .into_iter()
4662 .map(YEventChange::from)
4663 .collect();
4664
4665 let out = delta.into_boxed_slice();
4666 *len = out.len() as u32;
4667 Box::into_raw(out) as *mut _
4668}
4669
4670#[no_mangle]
4672pub unsafe extern "C" fn ytext_delta_destroy(delta: *mut YDeltaOut, len: u32) {
4673 if !delta.is_null() {
4674 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4675 drop(delta);
4676 }
4677}
4678
4679#[no_mangle]
4681pub unsafe extern "C" fn yevent_delta_destroy(delta: *mut YEventChange, len: u32) {
4682 if !delta.is_null() {
4683 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4684 drop(delta);
4685 }
4686}
4687
4688#[no_mangle]
4695pub unsafe extern "C" fn ymap_event_keys(
4696 e: *const YMapEvent,
4697 len: *mut u32,
4698) -> *mut YEventKeyChange {
4699 assert!(!e.is_null());
4700 let e = &*e;
4701 let delta: Vec<_> = e
4702 .keys(e.txn())
4703 .into_iter()
4704 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4705 .collect();
4706
4707 let out = delta.into_boxed_slice();
4708 *len = out.len() as u32;
4709 Box::into_raw(out) as *mut _
4710}
4711
4712#[no_mangle]
4718pub unsafe extern "C" fn yxmlelem_event_keys(
4719 e: *const YXmlEvent,
4720 len: *mut u32,
4721) -> *mut YEventKeyChange {
4722 assert!(!e.is_null());
4723 let e = &*e;
4724 let delta: Vec<_> = e
4725 .keys(e.txn())
4726 .into_iter()
4727 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4728 .collect();
4729
4730 let out = delta.into_boxed_slice();
4731 *len = out.len() as u32;
4732 Box::into_raw(out) as *mut _
4733}
4734
4735#[no_mangle]
4741pub unsafe extern "C" fn yxmltext_event_keys(
4742 e: *const YXmlTextEvent,
4743 len: *mut u32,
4744) -> *mut YEventKeyChange {
4745 assert!(!e.is_null());
4746 let e = &*e;
4747 let delta: Vec<_> = e
4748 .keys(e.txn())
4749 .into_iter()
4750 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4751 .collect();
4752
4753 let out = delta.into_boxed_slice();
4754 *len = out.len() as u32;
4755 Box::into_raw(out) as *mut _
4756}
4757
4758#[no_mangle]
4761pub unsafe extern "C" fn yevent_keys_destroy(keys: *mut YEventKeyChange, len: u32) {
4762 if !keys.is_null() {
4763 drop(Vec::from_raw_parts(keys, len as usize, len as usize));
4764 }
4765}
4766
4767pub type YUndoManager = yrs::undo::UndoManager<AtomicPtr<c_void>>;
4768
4769#[repr(C)]
4770pub struct YUndoManagerOptions {
4771 pub capture_timeout_millis: i32,
4772}
4773
4774#[no_mangle]
4782pub unsafe extern "C" fn yundo_manager(options: *const YUndoManagerOptions) -> *mut YUndoManager {
4783 let mut o = yrs::undo::Options::default();
4784 if let Some(options) = options.as_ref() {
4785 if options.capture_timeout_millis >= 0 {
4786 o.capture_timeout_millis = options.capture_timeout_millis as u64;
4787 }
4788 };
4789 let boxed = Box::new(yrs::undo::UndoManager::with_options(o));
4790 Box::into_raw(boxed)
4791}
4792
4793#[no_mangle]
4795pub unsafe extern "C" fn yundo_manager_destroy(mgr: *mut YUndoManager) {
4796 drop(Box::from_raw(mgr));
4797}
4798
4799#[no_mangle]
4804pub unsafe extern "C" fn yundo_manager_add_origin(
4805 mgr: *mut YUndoManager,
4806 origin_len: u32,
4807 origin: *const c_char,
4808) {
4809 let mgr = mgr.as_mut().unwrap();
4810 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4811 mgr.include_origin(Origin::from(bytes));
4812}
4813
4814#[no_mangle]
4816pub unsafe extern "C" fn yundo_manager_remove_origin(
4817 mgr: *mut YUndoManager,
4818 origin_len: u32,
4819 origin: *const c_char,
4820) {
4821 let mgr = mgr.as_mut().unwrap();
4822 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4823 mgr.exclude_origin(Origin::from(bytes));
4824}
4825
4826#[no_mangle]
4828pub unsafe extern "C" fn yundo_manager_add_scope(
4829 mgr: *mut YUndoManager,
4830 doc: *const Doc,
4831 ytype: *const Branch,
4832) {
4833 let mgr = mgr.as_mut().unwrap();
4834 let doc = doc.as_ref().unwrap();
4835 let branch = ytype.as_ref().unwrap();
4836 mgr.expand_scope(doc, &BranchPtr::from(branch));
4837}
4838
4839#[no_mangle]
4848pub unsafe extern "C" fn yundo_manager_clear(mgr: *mut YUndoManager) {
4849 let mgr = mgr.as_mut().unwrap();
4850 mgr.clear_all();
4851}
4852
4853#[no_mangle]
4860pub unsafe extern "C" fn yundo_manager_stop(mgr: *mut YUndoManager) {
4861 let mgr = mgr.as_mut().unwrap();
4862 mgr.reset();
4863}
4864
4865#[no_mangle]
4872pub unsafe extern "C" fn yundo_manager_undo(mgr: *mut YUndoManager) -> u8 {
4873 let mgr = mgr.as_mut().unwrap();
4874
4875 if mgr.undo_blocking() {
4876 Y_TRUE
4877 } else {
4878 Y_FALSE
4879 }
4880}
4881
4882#[no_mangle]
4888pub unsafe extern "C" fn yundo_manager_redo(mgr: *mut YUndoManager) -> u8 {
4889 let mgr = mgr.as_mut().unwrap();
4890 if mgr.redo_blocking() {
4891 Y_TRUE
4892 } else {
4893 Y_FALSE
4894 }
4895}
4896
4897#[no_mangle]
4899pub unsafe extern "C" fn yundo_manager_undo_stack_len(mgr: *mut YUndoManager) -> u32 {
4900 let mgr = mgr.as_mut().unwrap();
4901 mgr.undo_stack().len() as u32
4902}
4903
4904#[no_mangle]
4906pub unsafe extern "C" fn yundo_manager_redo_stack_len(mgr: *mut YUndoManager) -> u32 {
4907 let mgr = mgr.as_mut().unwrap();
4908 mgr.redo_stack().len() as u32
4909}
4910
4911#[no_mangle]
4915pub unsafe extern "C" fn yundo_manager_observe_added(
4916 mgr: *mut YUndoManager,
4917 key_len: u32,
4918 key: *const c_char,
4919 state: *mut c_void,
4920 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4921) {
4922 let state = CallbackState::new(state);
4923 let mgr = mgr.as_mut().unwrap();
4924 mgr.observe_item_added(origin(key_len, key), move |_, e| {
4925 let meta_ptr = {
4926 let event = YUndoEvent::new(e);
4927 callback(state.0, &event as *const YUndoEvent);
4928 event.meta
4929 };
4930 e.meta().store(meta_ptr, Ordering::Release);
4931 });
4932}
4933
4934#[no_mangle]
4937pub unsafe extern "C" fn yundo_manager_unobserve_added(
4938 mgr: *mut YUndoManager,
4939 key_len: u32,
4940 key: *const c_char,
4941) -> u8 {
4942 let mgr = mgr.as_mut().unwrap();
4943 mgr.unobserve_item_added(origin(key_len, key)) as u8
4944}
4945
4946#[no_mangle]
4950pub unsafe extern "C" fn yundo_manager_observe_popped(
4951 mgr: *mut YUndoManager,
4952 key_len: u32,
4953 key: *const c_char,
4954 state: *mut c_void,
4955 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4956) {
4957 let mgr = mgr.as_mut().unwrap();
4958 let state = CallbackState::new(state);
4959 mgr.observe_item_popped(origin(key_len, key), move |_, e| {
4960 let meta_ptr = {
4961 let event = YUndoEvent::new(e);
4962 callback(state.0, &event as *const YUndoEvent);
4963 event.meta
4964 };
4965 e.meta().store(meta_ptr, Ordering::Release);
4966 });
4967}
4968
4969#[no_mangle]
4972pub unsafe extern "C" fn yundo_manager_unobserve_popped(
4973 mgr: *mut YUndoManager,
4974 key_len: u32,
4975 key: *const c_char,
4976) -> u8 {
4977 let mgr = mgr.as_mut().unwrap();
4978 mgr.unobserve_item_popped(origin(key_len, key)) as u8
4979}
4980
4981pub const Y_KIND_UNDO: c_char = 0;
4982pub const Y_KIND_REDO: c_char = 1;
4983
4984#[repr(C)]
4988pub struct YUndoEvent {
4989 pub kind: c_char,
4992 pub origin: *const c_char,
4995 pub origin_len: u32,
4999 pub meta: *mut c_void,
5009}
5010
5011impl YUndoEvent {
5012 unsafe fn new(e: &yrs::undo::Event<AtomicPtr<c_void>>) -> Self {
5013 let (origin, origin_len) = if let Some(origin) = e.origin() {
5014 let bytes = origin.as_ref();
5015 let origin_len = bytes.len() as u32;
5016 let origin = bytes.as_ptr() as *const c_char;
5017 (origin, origin_len)
5018 } else {
5019 (null(), 0)
5020 };
5021 YUndoEvent {
5022 kind: match e.kind() {
5023 EventKind::Undo => Y_KIND_UNDO,
5024 EventKind::Redo => Y_KIND_REDO,
5025 },
5026 origin,
5027 origin_len,
5028 meta: e.meta().load(Ordering::Acquire),
5029 }
5030 }
5031}
5032
5033#[no_mangle]
5037pub unsafe extern "C" fn ytype_kind(branch: *const Branch) -> i8 {
5038 if let Some(branch) = branch.as_ref() {
5039 match branch.type_ref() {
5040 TypeRef::Array => Y_ARRAY,
5041 TypeRef::Map => Y_MAP,
5042 TypeRef::Text => Y_TEXT,
5043 TypeRef::XmlElement(_) => Y_XML_ELEM,
5044 TypeRef::XmlText => Y_XML_TEXT,
5045 TypeRef::XmlFragment => Y_XML_FRAG,
5046 TypeRef::SubDoc => Y_DOC,
5047 TypeRef::WeakLink(_) => Y_WEAK_LINK,
5048 TypeRef::XmlHook => 0,
5049 TypeRef::Undefined => 0,
5050 }
5051 } else {
5052 0
5053 }
5054}
5055
5056pub const Y_EVENT_PATH_KEY: c_char = 1;
5058
5059pub const Y_EVENT_PATH_INDEX: c_char = 2;
5061
5062#[repr(C)]
5070pub struct YPathSegment {
5071 pub tag: c_char,
5079
5080 pub value: YPathSegmentCase,
5083}
5084
5085impl From<PathSegment> for YPathSegment {
5086 fn from(ps: PathSegment) -> Self {
5087 match ps {
5088 PathSegment::Key(key) => {
5089 let key = CString::new(key.as_ref()).unwrap().into_raw() as *const _;
5090 YPathSegment {
5091 tag: Y_EVENT_PATH_KEY,
5092 value: YPathSegmentCase { key },
5093 }
5094 }
5095 PathSegment::Index(index) => YPathSegment {
5096 tag: Y_EVENT_PATH_INDEX,
5097 value: YPathSegmentCase {
5098 index: index as u32,
5099 },
5100 },
5101 }
5102 }
5103}
5104
5105impl Drop for YPathSegment {
5106 fn drop(&mut self) {
5107 if self.tag == Y_EVENT_PATH_KEY {
5108 unsafe {
5109 ystring_destroy(self.value.key as *mut _);
5110 }
5111 }
5112 }
5113}
5114
5115#[repr(C)]
5116pub union YPathSegmentCase {
5117 pub key: *const c_char,
5118 pub index: u32,
5119}
5120
5121pub const Y_EVENT_CHANGE_ADD: u8 = 1;
5124
5125pub const Y_EVENT_CHANGE_DELETE: u8 = 2;
5128
5129pub const Y_EVENT_CHANGE_RETAIN: u8 = 3;
5132
5133#[repr(C)]
5149pub struct YEventChange {
5150 pub tag: u8,
5160
5161 pub len: u32,
5164
5165 pub values: *const YOutput,
5168}
5169
5170impl<'a> From<&'a Change> for YEventChange {
5171 fn from(change: &'a Change) -> Self {
5172 match change {
5173 Change::Added(values) => {
5174 let out: Vec<_> = values
5175 .into_iter()
5176 .map(|v| YOutput::from(v.clone()))
5177 .collect();
5178 let len = out.len() as u32;
5179 let out = out.into_boxed_slice();
5180 let values = Box::into_raw(out) as *mut _;
5181
5182 YEventChange {
5183 tag: Y_EVENT_CHANGE_ADD,
5184 len,
5185 values,
5186 }
5187 }
5188 Change::Removed(len) => YEventChange {
5189 tag: Y_EVENT_CHANGE_DELETE,
5190 len: *len as u32,
5191 values: null(),
5192 },
5193 Change::Retain(len) => YEventChange {
5194 tag: Y_EVENT_CHANGE_RETAIN,
5195 len: *len as u32,
5196 values: null(),
5197 },
5198 }
5199 }
5200}
5201
5202impl Drop for YEventChange {
5203 fn drop(&mut self) {
5204 if self.tag == Y_EVENT_CHANGE_ADD {
5205 unsafe {
5206 let len = self.len as usize;
5207 let values = Vec::from_raw_parts(self.values as *mut YOutput, len, len);
5208 drop(values);
5209 }
5210 }
5211 }
5212}
5213
5214#[repr(C)]
5233pub struct YDeltaOut {
5234 pub tag: u8,
5244
5245 pub len: u32,
5248
5249 pub attributes_len: u32,
5251
5252 pub attributes: *mut YDeltaAttr,
5255
5256 pub insert: *mut YOutput,
5259}
5260
5261impl YDeltaOut {
5262 fn insert(value: &Out, attrs: &Option<Box<Attrs>>) -> Self {
5263 let insert = Box::into_raw(Box::new(YOutput::from(value.clone())));
5264 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5265 let len = attrs.len() as u32;
5266 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5267 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5268 (len, attrs)
5269 } else {
5270 (0, null_mut())
5271 };
5272
5273 YDeltaOut {
5274 tag: Y_EVENT_CHANGE_ADD,
5275 len: 1,
5276 insert,
5277 attributes_len,
5278 attributes,
5279 }
5280 }
5281
5282 fn retain(len: u32, attrs: &Option<Box<Attrs>>) -> Self {
5283 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5284 let len = attrs.len() as u32;
5285 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5286 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5287 (len, attrs)
5288 } else {
5289 (0, null_mut())
5290 };
5291 YDeltaOut {
5292 tag: Y_EVENT_CHANGE_RETAIN,
5293 len,
5294 insert: null_mut(),
5295 attributes_len,
5296 attributes,
5297 }
5298 }
5299
5300 fn delete(len: u32) -> Self {
5301 YDeltaOut {
5302 tag: Y_EVENT_CHANGE_DELETE,
5303 len,
5304 insert: null_mut(),
5305 attributes_len: 0,
5306 attributes: null_mut(),
5307 }
5308 }
5309}
5310
5311impl<'a> From<&'a Delta> for YDeltaOut {
5312 fn from(d: &Delta) -> Self {
5313 match d {
5314 Delta::Inserted(value, attrs) => YDeltaOut::insert(value, attrs),
5315 Delta::Retain(len, attrs) => YDeltaOut::retain(*len, attrs),
5316 Delta::Deleted(len) => YDeltaOut::delete(*len),
5317 }
5318 }
5319}
5320
5321impl Drop for YDeltaOut {
5322 fn drop(&mut self) {
5323 unsafe {
5324 if !self.attributes.is_null() {
5325 let len = self.attributes_len as usize;
5326 drop(Vec::from_raw_parts(self.attributes, len, len));
5327 }
5328 if !self.insert.is_null() {
5329 drop(Box::from_raw(self.insert));
5330 }
5331 }
5332 }
5333}
5334
5335#[repr(C)]
5337pub struct YDeltaAttr {
5338 pub key: *const c_char,
5340 pub value: YOutput,
5342}
5343
5344impl YDeltaAttr {
5345 fn new(k: &Arc<str>, v: &Any) -> Self {
5346 let key = CString::new(k.as_ref()).unwrap().into_raw() as *const _;
5347 let value = YOutput::from(v);
5348 YDeltaAttr { key, value }
5349 }
5350}
5351
5352impl Drop for YDeltaAttr {
5353 fn drop(&mut self) {
5354 unsafe { ystring_destroy(self.key as *mut _) }
5355 }
5356}
5357
5358#[repr(C)]
5373pub struct YDeltaIn {
5374 pub tag: u8,
5384
5385 pub len: u32,
5388
5389 pub attributes: *const YInput,
5392
5393 pub insert: *const YInput,
5396}
5397
5398impl YDeltaIn {
5399 fn as_input(&self) -> Delta<YInput> {
5400 match self.tag {
5401 Y_EVENT_CHANGE_RETAIN => {
5402 let attrs = if self.attributes.is_null() {
5403 None
5404 } else {
5405 let attrs = unsafe { self.attributes.read() };
5406 map_attrs(attrs.into()).map(Box::new)
5407 };
5408 Delta::Retain(self.len, attrs)
5409 }
5410 Y_EVENT_CHANGE_DELETE => Delta::Deleted(self.len),
5411 Y_EVENT_CHANGE_ADD => {
5412 let attrs = if self.attributes.is_null() {
5413 None
5414 } else {
5415 let attrs = unsafe { self.attributes.read() };
5416 map_attrs(attrs.into()).map(Box::new)
5417 };
5418 let input = unsafe { self.insert.read() };
5419 Delta::Inserted(input, attrs)
5420 }
5421 tag => panic!("YDelta tag identifier is of unknown type: {}", tag),
5422 }
5423 }
5424}
5425
5426pub const Y_EVENT_KEY_CHANGE_ADD: c_char = 4;
5429
5430pub const Y_EVENT_KEY_CHANGE_DELETE: c_char = 5;
5433
5434pub const Y_EVENT_KEY_CHANGE_UPDATE: c_char = 6;
5437
5438#[repr(C)]
5451pub struct YEventKeyChange {
5452 pub key: *const c_char,
5454 pub tag: c_char,
5464
5465 pub old_value: *const YOutput,
5467
5468 pub new_value: *const YOutput,
5470}
5471
5472impl YEventKeyChange {
5473 fn new(key: &str, change: &EntryChange) -> Self {
5474 let key = CString::new(key).unwrap().into_raw() as *const _;
5475 match change {
5476 EntryChange::Inserted(new) => YEventKeyChange {
5477 key,
5478 tag: Y_EVENT_KEY_CHANGE_ADD,
5479 old_value: null(),
5480 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5481 },
5482 EntryChange::Updated(old, new) => YEventKeyChange {
5483 key,
5484 tag: Y_EVENT_KEY_CHANGE_UPDATE,
5485 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5486 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5487 },
5488 EntryChange::Removed(old) => YEventKeyChange {
5489 key,
5490 tag: Y_EVENT_KEY_CHANGE_DELETE,
5491 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5492 new_value: null(),
5493 },
5494 }
5495 }
5496}
5497
5498impl Drop for YEventKeyChange {
5499 fn drop(&mut self) {
5500 unsafe {
5501 ystring_destroy(self.key as *mut _);
5502 youtput_destroy(self.old_value as *mut _);
5503 youtput_destroy(self.new_value as *mut _);
5504 }
5505 }
5506}
5507
5508trait BranchPointable {
5509 fn into_raw_branch(self) -> *mut Branch;
5510 fn from_raw_branch(branch: *const Branch) -> Self;
5511}
5512
5513impl<T> BranchPointable for T
5514where
5515 T: AsRef<Branch> + From<BranchPtr>,
5516{
5517 fn into_raw_branch(self) -> *mut Branch {
5518 let branch_ref = self.as_ref();
5519 branch_ref as *const Branch as *mut Branch
5520 }
5521
5522 fn from_raw_branch(branch: *const Branch) -> Self {
5523 let b = unsafe { branch.as_ref().unwrap() };
5524 let branch_ref = BranchPtr::from(b);
5525 T::from(branch_ref)
5526 }
5527}
5528
5529#[repr(transparent)]
5540pub struct YStickyIndex(StickyIndex);
5541
5542impl From<StickyIndex> for YStickyIndex {
5543 #[inline(always)]
5544 fn from(value: StickyIndex) -> Self {
5545 YStickyIndex(value)
5546 }
5547}
5548
5549#[no_mangle]
5551pub unsafe extern "C" fn ysticky_index_destroy(pos: *mut YStickyIndex) {
5552 drop(Box::from_raw(pos))
5553}
5554
5555#[no_mangle]
5559pub unsafe extern "C" fn ysticky_index_assoc(pos: *const YStickyIndex) -> i8 {
5560 let pos = pos.as_ref().unwrap();
5561 match pos.0.assoc {
5562 Assoc::After => 0,
5563 Assoc::Before => -1,
5564 }
5565}
5566
5567#[no_mangle]
5574pub unsafe extern "C" fn ysticky_index_from_index(
5575 branch: *const Branch,
5576 txn: *mut Transaction,
5577 index: u32,
5578 assoc: i8,
5579) -> *mut YStickyIndex {
5580 assert!(!branch.is_null());
5581 assert!(!txn.is_null());
5582
5583 let branch = BranchPtr::from_raw_branch(branch);
5584 let txn = txn.as_mut().unwrap();
5585 let index = index as u32;
5586 let assoc = if assoc >= 0 {
5587 Assoc::After
5588 } else {
5589 Assoc::Before
5590 };
5591
5592 if let Some(txn) = txn.as_mut() {
5593 if let Some(pos) = StickyIndex::at(txn, branch, index, assoc) {
5594 Box::into_raw(Box::new(YStickyIndex(pos)))
5595 } else {
5596 null_mut()
5597 }
5598 } else {
5599 panic!("ysticky_index_from_index requires a read-write transaction");
5600 }
5601}
5602
5603#[no_mangle]
5606pub unsafe extern "C" fn ysticky_index_encode(
5607 pos: *const YStickyIndex,
5608 len: *mut u32,
5609) -> *mut c_char {
5610 let pos = pos.as_ref().unwrap();
5611 let binary = pos.0.encode_v1().into_boxed_slice();
5612 *len = binary.len() as u32;
5613 Box::into_raw(binary) as *mut c_char
5614}
5615
5616#[no_mangle]
5619pub unsafe extern "C" fn ysticky_index_decode(
5620 binary: *const c_char,
5621 len: u32,
5622) -> *mut YStickyIndex {
5623 let slice = std::slice::from_raw_parts(binary as *const u8, len as usize);
5624 if let Ok(pos) = StickyIndex::decode_v1(slice) {
5625 Box::into_raw(Box::new(YStickyIndex(pos)))
5626 } else {
5627 null_mut()
5628 }
5629}
5630
5631#[no_mangle]
5635pub unsafe extern "C" fn ysticky_index_to_json(pos: *const YStickyIndex) -> *mut c_char {
5636 let pos = pos.as_ref().unwrap();
5637 let json = match serde_json::to_string(&pos.0) {
5638 Ok(json) => json,
5639 Err(_) => return null_mut(),
5640 };
5641 CString::new(json).unwrap().into_raw()
5642}
5643
5644#[no_mangle]
5653pub unsafe extern "C" fn ysticky_index_from_json(json: *const c_char) -> *mut YStickyIndex {
5654 let cstr = CStr::from_ptr(json);
5655 let json = match cstr.to_str() {
5656 Ok(json) => json,
5657 Err(_) => return null_mut(),
5658 };
5659 match serde_json::from_str(json) {
5660 Ok(pos) => Box::into_raw(Box::new(YStickyIndex(pos))),
5661 Err(_) => null_mut(),
5662 }
5663}
5664
5665#[no_mangle]
5671pub unsafe extern "C" fn ysticky_index_read(
5672 pos: *const YStickyIndex,
5673 txn: *const Transaction,
5674 out_branch: *mut *mut Branch,
5675 out_index: *mut u32,
5676) {
5677 let pos = pos.as_ref().unwrap();
5678 let txn = txn.as_ref().unwrap();
5679
5680 if let Some(abs) = pos.0.get_offset(txn) {
5681 *out_branch = abs.branch.as_ref() as *const Branch as *mut Branch;
5682 *out_index = abs.index as u32;
5683 }
5684}
5685
5686pub type Weak = LinkSource;
5687
5688#[no_mangle]
5689pub unsafe extern "C" fn yweak_destroy(weak: *const Weak) {
5690 drop(Arc::from_raw(weak));
5691}
5692
5693#[no_mangle]
5694pub unsafe extern "C" fn yweak_deref(
5695 map_link: *const Branch,
5696 txn: *const Transaction,
5697) -> *mut YOutput {
5698 assert!(!map_link.is_null());
5699 assert!(!txn.is_null());
5700
5701 let txn = txn.as_ref().unwrap();
5702 let weak: WeakRef<MapRef> = WeakRef::from_raw_branch(map_link);
5703 if let Some(value) = weak.try_deref_value(txn) {
5704 Box::into_raw(Box::new(YOutput::from(value)))
5705 } else {
5706 null_mut()
5707 }
5708}
5709
5710#[no_mangle]
5711pub unsafe extern "C" fn yweak_read(
5712 text_link: *const Branch,
5713 txn: *const Transaction,
5714 out_branch: *mut *mut Branch,
5715 out_start_index: *mut u32,
5716 out_end_index: *mut u32,
5717) {
5718 assert!(!text_link.is_null());
5719 assert!(!txn.is_null());
5720
5721 let txn = txn.as_ref().unwrap();
5722 let weak: WeakRef<BranchPtr> = WeakRef::from_raw_branch(text_link);
5723 if let Some(id) = weak.start_id() {
5724 let start = StickyIndex::from_id(*id, Assoc::After);
5726 assert!(weak.end_id() != None);
5727 let end = StickyIndex::from_id(*weak.end_id().unwrap(), Assoc::After);
5728 if let Some(start_pos) = start.get_offset(txn) {
5729 *out_branch = start_pos.branch.as_ref() as *const Branch as *mut Branch;
5730 *out_start_index = start_pos.index as u32;
5731 if let Some(end_pos) = end.get_offset(txn) {
5732 assert!(*out_branch == end_pos.branch.as_ref() as *const Branch as *mut Branch);
5733 *out_end_index = end_pos.index as u32;
5734 }
5735 }
5736 } else {
5737 assert!(weak.end_id() == None); *out_start_index = 0; *out_end_index = 0; }
5742}
5743
5744#[no_mangle]
5745pub unsafe extern "C" fn yweak_iter(
5746 array_link: *const Branch,
5747 txn: *const Transaction,
5748) -> *mut WeakIter {
5749 assert!(!array_link.is_null());
5750 assert!(!txn.is_null());
5751
5752 let txn = txn.as_ref().unwrap();
5753 let weak: WeakRef<ArrayRef> = WeakRef::from_raw_branch(array_link);
5754 let iter: NativeUnquote<'static, Transaction> = std::mem::transmute(weak.unquote(txn));
5755
5756 Box::into_raw(Box::new(WeakIter(iter)))
5757}
5758
5759#[no_mangle]
5760pub unsafe extern "C" fn yweak_iter_destroy(iter: *mut WeakIter) {
5761 drop(Box::from_raw(iter))
5762}
5763
5764#[no_mangle]
5765pub unsafe extern "C" fn yweak_iter_next(iter: *mut WeakIter) -> *mut YOutput {
5766 assert!(!iter.is_null());
5767 let iter = iter.as_mut().unwrap();
5768
5769 if let Some(value) = iter.0.next() {
5770 Box::into_raw(Box::new(YOutput::from(value)))
5771 } else {
5772 null_mut()
5773 }
5774}
5775
5776#[no_mangle]
5777pub unsafe extern "C" fn yweak_string(
5778 text_link: *const Branch,
5779 txn: *const Transaction,
5780) -> *mut c_char {
5781 assert!(!text_link.is_null());
5782 assert!(!txn.is_null());
5783
5784 let txn = txn.as_ref().unwrap();
5785 let weak: WeakRef<TextRef> = WeakRef::from_raw_branch(text_link);
5786
5787 let str = weak.get_string(txn);
5788 CString::new(str).unwrap().into_raw()
5789}
5790
5791#[no_mangle]
5792pub unsafe extern "C" fn yweak_xml_string(
5793 xml_text_link: *const Branch,
5794 txn: *const Transaction,
5795) -> *mut c_char {
5796 assert!(!xml_text_link.is_null());
5797 assert!(!txn.is_null());
5798
5799 let txn = txn.as_ref().unwrap();
5800 let weak: WeakRef<XmlTextRef> = WeakRef::from_raw_branch(xml_text_link);
5801
5802 let str = weak.get_string(txn);
5803 CString::new(str).unwrap().into_raw()
5804}
5805
5806#[no_mangle]
5810pub unsafe extern "C" fn yweak_observe(
5811 weak: *const Branch,
5812 key_len: u32,
5813 key: *const c_char,
5814 state: *mut c_void,
5815 cb: extern "C" fn(*mut c_void, *const YWeakLinkEvent),
5816) {
5817 assert!(!weak.is_null());
5818
5819 let state = CallbackState::new(state);
5820 let txt: WeakRef<BranchPtr> = WeakRef::from_raw_branch(weak);
5821 txt.observe(origin(key_len, key), move |txn, e| {
5822 let e = YWeakLinkEvent::new(e, txn);
5823 cb(state.0, &e as *const YWeakLinkEvent);
5824 });
5825}
5826
5827#[no_mangle]
5828pub unsafe extern "C" fn ymap_link(
5829 map: *const Branch,
5830 txn: *const Transaction,
5831 key: *const c_char,
5832) -> *const Weak {
5833 assert!(!map.is_null());
5834 assert!(!txn.is_null());
5835
5836 let txn = txn.as_ref().unwrap();
5837 let map = MapRef::from_raw_branch(map);
5838 let key = CStr::from_ptr(key).to_str().unwrap();
5839 if let Some(weak) = map.link(txn, key) {
5840 let source = weak.source();
5841 Arc::into_raw(source.clone())
5842 } else {
5843 null()
5844 }
5845}
5846
5847#[no_mangle]
5848pub unsafe extern "C" fn ytext_quote(
5849 text: *const Branch,
5850 txn: *mut Transaction,
5851 start_index: *mut u32,
5852 end_index: *mut u32,
5853 start_exclusive: i8,
5854 end_exclusive: i8,
5855) -> *const Weak {
5856 assert!(!text.is_null());
5857 assert!(!txn.is_null());
5858
5859 let text = TextRef::from_raw_branch(text);
5860 let txn = txn.as_mut().unwrap();
5861 let txn = txn
5862 .as_mut()
5863 .expect("provided transaction was not writeable");
5864
5865 let start_index = start_index.as_ref().cloned();
5866 let end_index = end_index.as_ref().cloned();
5867 let range = ExplicitRange {
5868 start_index,
5869 end_index,
5870 start_exclusive,
5871 end_exclusive,
5872 };
5873 if let Ok(weak) = text.quote(txn, range) {
5874 let source = weak.source();
5875 Arc::into_raw(source.clone())
5876 } else {
5877 null()
5878 }
5879}
5880
5881#[no_mangle]
5882pub unsafe extern "C" fn yarray_quote(
5883 array: *const Branch,
5884 txn: *mut Transaction,
5885 start_index: *mut u32,
5886 end_index: *mut u32,
5887 start_exclusive: i8,
5888 end_exclusive: i8,
5889) -> *const Weak {
5890 assert!(!array.is_null());
5891 assert!(!txn.is_null());
5892
5893 let array = ArrayRef::from_raw_branch(array);
5894 let txn = txn.as_mut().unwrap();
5895 let txn = txn
5896 .as_mut()
5897 .expect("provided transaction was not writeable");
5898
5899 let start_index = start_index.as_ref().cloned();
5900 let end_index = end_index.as_ref().cloned();
5901 let range = ExplicitRange {
5902 start_index,
5903 end_index,
5904 start_exclusive,
5905 end_exclusive,
5906 };
5907 if let Ok(weak) = array.quote(txn, range) {
5908 let source = weak.source();
5909 Arc::into_raw(source.clone())
5910 } else {
5911 null()
5912 }
5913}
5914
5915struct ExplicitRange {
5916 start_index: Option<u32>,
5917 end_index: Option<u32>,
5918 start_exclusive: i8,
5919 end_exclusive: i8,
5920}
5921
5922impl RangeBounds<u32> for ExplicitRange {
5923 fn start_bound(&self) -> Bound<&u32> {
5924 match (&self.start_index, self.start_exclusive) {
5925 (None, _) => Bound::Unbounded,
5926 (Some(i), 0) => Bound::Included(i),
5927 (Some(i), _) => Bound::Excluded(i),
5928 }
5929 }
5930
5931 fn end_bound(&self) -> Bound<&u32> {
5932 match (&self.end_index, self.end_exclusive) {
5933 (None, _) => Bound::Unbounded,
5934 (Some(i), 0) => Bound::Included(i),
5935 (Some(i), _) => Bound::Excluded(i),
5936 }
5937 }
5938}
5939
5940#[repr(C)]
5948pub struct YBranchId {
5949 pub client_or_len: i64,
5952 pub variant: YBranchIdVariant,
5953}
5954
5955#[repr(C)]
5956pub union YBranchIdVariant {
5957 pub clock: u32,
5959 pub name: *const u8,
5964}
5965
5966#[no_mangle]
5969pub unsafe extern "C" fn ybranch_id(branch: *const Branch) -> YBranchId {
5970 let branch = branch.as_ref().unwrap();
5971 match branch.id() {
5972 BranchID::Nested(id) => YBranchId {
5973 client_or_len: id.client.get() as i64,
5974 variant: YBranchIdVariant { clock: id.clock },
5975 },
5976 BranchID::Root(name) => {
5977 let len = -(name.len() as i64);
5978 YBranchId {
5979 client_or_len: len,
5980 variant: YBranchIdVariant {
5981 name: name.as_ptr(),
5982 },
5983 }
5984 }
5985 }
5986}
5987
5988#[no_mangle]
5994pub unsafe extern "C" fn ybranch_get(
5995 branch_id: *const YBranchId,
5996 txn: *mut Transaction,
5997) -> *mut Branch {
5998 let txn = txn.as_ref().unwrap();
5999 let branch_id = branch_id.as_ref().unwrap();
6000 let client_or_len = branch_id.client_or_len;
6001 let ptr = if client_or_len >= 0 {
6002 BranchID::get_nested(
6003 txn,
6004 &ID::new(ClientID::new(client_or_len as u64), branch_id.variant.clock),
6005 )
6006 } else {
6007 let name = std::slice::from_raw_parts(branch_id.variant.name, (-client_or_len) as usize);
6008 BranchID::get_root(txn, std::str::from_utf8_unchecked(name))
6009 };
6010
6011 match ptr {
6012 None => null_mut(),
6013 Some(branch_ptr) => branch_ptr.into_raw_branch(),
6014 }
6015}
6016
6017#[no_mangle]
6021pub unsafe extern "C" fn ybranch_alive(branch: *mut Branch) -> u8 {
6022 if branch.is_null() {
6023 Y_FALSE
6024 } else {
6025 let branch = BranchPtr::from_raw_branch(branch);
6026 if branch.is_deleted() {
6027 Y_FALSE
6028 } else {
6029 Y_TRUE
6030 }
6031 }
6032}
6033
6034#[no_mangle]
6041pub unsafe extern "C" fn ybranch_json(branch: *mut Branch, txn: *mut Transaction) -> *mut c_char {
6042 if branch.is_null() {
6043 std::ptr::null_mut()
6044 } else {
6045 let txn = txn.as_ref().unwrap();
6046 let branch_ref = BranchPtr::from_raw_branch(branch);
6047 let any = match branch_ref.type_ref() {
6048 TypeRef::Array => ArrayRef::from_raw_branch(branch).to_json(txn),
6049 TypeRef::Map => MapRef::from_raw_branch(branch).to_json(txn),
6050 TypeRef::Text => TextRef::from_raw_branch(branch).get_string(txn).into(),
6051 TypeRef::XmlElement(_) => XmlElementRef::from_raw_branch(branch)
6052 .get_string(txn)
6053 .into(),
6054 TypeRef::XmlFragment => XmlFragmentRef::from_raw_branch(branch)
6055 .get_string(txn)
6056 .into(),
6057 TypeRef::XmlText => XmlTextRef::from_raw_branch(branch).get_string(txn).into(),
6058 TypeRef::SubDoc | TypeRef::XmlHook | TypeRef::WeakLink(_) | TypeRef::Undefined => {
6059 return std::ptr::null_mut()
6060 }
6061 };
6062 let json = match serde_json::to_string(&any) {
6063 Ok(json) => json,
6064 Err(_) => return std::ptr::null_mut(),
6065 };
6066 CString::new(json).unwrap().into_raw()
6067 }
6068}