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::types::array::ArrayEvent;
13use yrs::types::array::ArrayIter as NativeArrayIter;
14use yrs::types::map::MapEvent;
15use yrs::types::map::MapIter as NativeMapIter;
16use yrs::types::text::{Diff, TextEvent, YChange};
17use yrs::types::weak::{LinkSource, Unquote as NativeUnquote, WeakEvent, WeakRef};
18use yrs::types::xml::{Attributes as NativeAttributes, XmlOut};
19use yrs::types::xml::{TreeWalker as NativeTreeWalker, XmlFragment};
20use yrs::types::xml::{XmlEvent, XmlTextEvent};
21use yrs::types::{Attrs, Change, Delta, EntryChange, Event, PathSegment, ToJson, TypeRef};
22use yrs::undo::EventKind;
23use yrs::updates::decoder::{Decode, DecoderV1};
24use yrs::updates::encoder::{Encode, Encoder, EncoderV1, EncoderV2};
25use yrs::{
26 uuid_v4, Any, Array, ArrayRef, Assoc, BranchID, DeleteSet, GetString, Map, MapRef, Observable,
27 OffsetKind, Options, Origin, Out, Quotable, ReadTxn, Snapshot, StateVector, StickyIndex, Store,
28 SubdocsEvent, SubdocsEventIter, Text, TextRef, Transact, TransactionCleanupEvent, Update, Xml,
29 XmlElementPrelim, XmlElementRef, XmlFragmentRef, XmlTextPrelim, XmlTextRef, ID,
30};
31
32pub const Y_JSON: i8 = -9;
35
36pub const Y_JSON_BOOL: i8 = -8;
38
39pub const Y_JSON_NUM: i8 = -7;
41
42pub const Y_JSON_INT: i8 = -6;
44
45pub const Y_JSON_STR: i8 = -5;
47
48pub const Y_JSON_BUF: i8 = -4;
50
51pub const Y_JSON_ARR: i8 = -3;
54
55pub const Y_JSON_MAP: i8 = -2;
58
59pub const Y_JSON_NULL: i8 = -1;
61
62pub const Y_JSON_UNDEF: i8 = 0;
64
65pub const Y_ARRAY: i8 = 1;
67
68pub const Y_MAP: i8 = 2;
70
71pub const Y_TEXT: i8 = 3;
73
74pub const Y_XML_ELEM: i8 = 4;
76
77pub const Y_XML_TEXT: i8 = 5;
79
80pub const Y_XML_FRAG: i8 = 6;
82
83pub const Y_DOC: i8 = 7;
85
86pub const Y_WEAK_LINK: i8 = 8;
88
89pub const Y_UNDEFINED: i8 = 9;
92
93pub const Y_TRUE: u8 = 1;
95
96pub const Y_FALSE: u8 = 0;
98
99pub const Y_OFFSET_BYTES: u8 = 0;
102
103pub const Y_OFFSET_UTF16: u8 = 1;
106
107pub type Doc = yrs::Doc;
117
118pub type Branch = yrs::branch::Branch;
126
127pub type Subscription = yrs::Subscription;
131
132#[repr(transparent)]
134pub struct ArrayIter(NativeArrayIter<&'static Transaction, Transaction>);
135
136#[repr(transparent)]
138pub struct WeakIter(NativeUnquote<'static, Transaction>);
139
140#[repr(transparent)]
143pub struct MapIter(NativeMapIter<'static, &'static Transaction, Transaction>);
144
145#[repr(transparent)]
149pub struct Attributes(NativeAttributes<'static, &'static Transaction, Transaction>);
150
151#[repr(transparent)]
156pub struct TreeWalker(NativeTreeWalker<'static, &'static Transaction, Transaction>);
157
158#[repr(transparent)]
162pub struct Transaction(TransactionInner);
163
164enum TransactionInner {
165 ReadOnly(yrs::Transaction<'static>),
166 ReadWrite(yrs::TransactionMut<'static>),
167}
168
169impl Transaction {
170 fn read_only(txn: yrs::Transaction) -> Self {
171 Transaction(TransactionInner::ReadOnly(unsafe {
172 std::mem::transmute(txn)
173 }))
174 }
175
176 fn read_write(txn: yrs::TransactionMut) -> Self {
177 Transaction(TransactionInner::ReadWrite(unsafe {
178 std::mem::transmute(txn)
179 }))
180 }
181
182 fn is_writeable(&self) -> bool {
183 match &self.0 {
184 TransactionInner::ReadOnly(_) => false,
185 TransactionInner::ReadWrite(_) => true,
186 }
187 }
188
189 fn as_mut(&mut self) -> Option<&mut yrs::TransactionMut<'static>> {
190 match &mut self.0 {
191 TransactionInner::ReadOnly(_) => None,
192 TransactionInner::ReadWrite(txn) => Some(txn),
193 }
194 }
195}
196
197impl ReadTxn for Transaction {
198 fn store(&self) -> &Store {
199 match &self.0 {
200 TransactionInner::ReadOnly(txn) => txn.store(),
201 TransactionInner::ReadWrite(txn) => txn.store(),
202 }
203 }
204}
205
206#[repr(C)]
209pub struct YMapEntry {
210 pub key: *const c_char,
212 pub value: *const YOutput,
215}
216
217impl YMapEntry {
218 fn new(key: &str, value: Box<YOutput>) -> Self {
219 let key = CString::new(key).unwrap().into_raw();
220 let value = Box::into_raw(value) as *const YOutput;
221 YMapEntry { key, value }
222 }
223}
224
225impl Drop for YMapEntry {
226 fn drop(&mut self) {
227 unsafe {
228 drop(CString::from_raw(self.key as *mut c_char));
229 drop(Box::from_raw(self.value as *mut YOutput));
230 }
231 }
232}
233
234#[repr(C)]
237pub struct YXmlAttr {
238 pub name: *const c_char,
239 pub value: *const c_char,
240}
241
242impl Drop for YXmlAttr {
243 fn drop(&mut self) {
244 unsafe {
245 drop(CString::from_raw(self.name as *mut _));
246 drop(CString::from_raw(self.value as *mut _));
247 }
248 }
249}
250
251#[repr(C)]
253pub struct YOptions {
254 pub id: u64,
261
262 pub guid: *const c_char,
265
266 pub collection_id: *const c_char,
269
270 pub encoding: u8,
276
277 pub skip_gc: u8,
280
281 pub auto_load: u8,
284
285 pub should_load: u8,
287}
288
289impl Into<Options> for YOptions {
290 fn into(self) -> Options {
291 let encoding = match self.encoding {
292 Y_OFFSET_BYTES => OffsetKind::Bytes,
293 Y_OFFSET_UTF16 => OffsetKind::Utf16,
294 _ => panic!("Unrecognized YOptions.encoding type"),
295 };
296 let guid = if self.guid.is_null() {
297 uuid_v4()
298 } else {
299 let c_str = unsafe { CStr::from_ptr(self.guid) };
300 let str = c_str.to_str().unwrap();
301 str.into()
302 };
303 let collection_id = if self.collection_id.is_null() {
304 None
305 } else {
306 let c_str = unsafe { CStr::from_ptr(self.collection_id) };
307 let str = Arc::from(c_str.to_str().unwrap());
308 Some(str)
309 };
310 Options {
311 client_id: self.id as ClientID,
312 guid,
313 collection_id,
314 skip_gc: if self.skip_gc == 0 { false } else { true },
315 auto_load: if self.auto_load == 0 { false } else { true },
316 should_load: if self.should_load == 0 { false } else { true },
317 offset_kind: encoding,
318 }
319 }
320}
321
322impl From<Options> for YOptions {
323 fn from(o: Options) -> Self {
324 YOptions {
325 id: o.client_id,
326 guid: CString::new(o.guid.as_ref()).unwrap().into_raw(),
327 collection_id: if let Some(collection_id) = o.collection_id {
328 CString::new(collection_id.to_string()).unwrap().into_raw()
329 } else {
330 null_mut()
331 },
332 encoding: match o.offset_kind {
333 OffsetKind::Bytes => Y_OFFSET_BYTES,
334 OffsetKind::Utf16 => Y_OFFSET_UTF16,
335 },
336 skip_gc: if o.skip_gc { 1 } else { 0 },
337 auto_load: if o.auto_load { 1 } else { 0 },
338 should_load: if o.should_load { 1 } else { 0 },
339 }
340 }
341}
342
343#[no_mangle]
345pub unsafe extern "C" fn yoptions() -> YOptions {
346 Options::default().into()
347}
348
349#[no_mangle]
351pub unsafe extern "C" fn ydoc_destroy(value: *mut Doc) {
352 if !value.is_null() {
353 drop(Box::from_raw(value));
354 }
355}
356
357#[no_mangle]
359pub unsafe extern "C" fn ymap_entry_destroy(value: *mut YMapEntry) {
360 if !value.is_null() {
361 drop(Box::from_raw(value));
362 }
363}
364
365#[no_mangle]
367pub unsafe extern "C" fn yxmlattr_destroy(attr: *mut YXmlAttr) {
368 if !attr.is_null() {
369 drop(Box::from_raw(attr));
370 }
371}
372
373#[no_mangle]
376pub unsafe extern "C" fn ystring_destroy(str: *mut c_char) {
377 if !str.is_null() {
378 drop(CString::from_raw(str));
379 }
380}
381
382#[no_mangle]
387pub unsafe extern "C" fn ybinary_destroy(ptr: *mut c_char, len: u32) {
388 if !ptr.is_null() {
389 drop(Vec::from_raw_parts(ptr, len as usize, len as usize));
390 }
391}
392
393#[no_mangle]
397pub extern "C" fn ydoc_new() -> *mut Doc {
398 Box::into_raw(Box::new(Doc::new()))
399}
400
401#[no_mangle]
407pub unsafe extern "C" fn ydoc_clone(doc: *mut Doc) -> *mut Doc {
408 let doc = doc.as_mut().unwrap();
409 Box::into_raw(Box::new(doc.clone()))
410}
411
412#[no_mangle]
416pub extern "C" fn ydoc_new_with_options(options: YOptions) -> *mut Doc {
417 Box::into_raw(Box::new(Doc::with_options(options.into())))
418}
419
420#[no_mangle]
422pub unsafe extern "C" fn ydoc_id(doc: *mut Doc) -> u64 {
423 let doc = doc.as_ref().unwrap();
424 doc.client_id()
425}
426
427#[no_mangle]
431pub unsafe extern "C" fn ydoc_guid(doc: *mut Doc) -> *mut c_char {
432 let doc = doc.as_ref().unwrap();
433 let uid = doc.guid();
434 CString::new(uid.as_ref()).unwrap().into_raw()
435}
436
437#[no_mangle]
442pub unsafe extern "C" fn ydoc_collection_id(doc: *mut Doc) -> *mut c_char {
443 let doc = doc.as_ref().unwrap();
444 if let Some(cid) = doc.collection_id() {
445 CString::new(cid.as_ref()).unwrap().into_raw()
446 } else {
447 null_mut()
448 }
449}
450
451#[no_mangle]
454pub unsafe extern "C" fn ydoc_should_load(doc: *mut Doc) -> u8 {
455 let doc = doc.as_ref().unwrap();
456 doc.should_load() as u8
457}
458
459#[no_mangle]
462pub unsafe extern "C" fn ydoc_auto_load(doc: *mut Doc) -> u8 {
463 let doc = doc.as_ref().unwrap();
464 doc.auto_load() as u8
465}
466
467#[repr(transparent)]
468struct CallbackState(*mut c_void);
469
470unsafe impl Send for CallbackState {}
471unsafe impl Sync for CallbackState {}
472
473impl CallbackState {
474 #[inline]
475 fn new(state: *mut c_void) -> Self {
476 CallbackState(state)
477 }
478}
479
480#[no_mangle]
481pub unsafe extern "C" fn ydoc_observe_updates_v1(
482 doc: *mut Doc,
483 state: *mut c_void,
484 cb: extern "C" fn(*mut c_void, u32, *const c_char),
485) -> *mut Subscription {
486 let state = CallbackState::new(state);
487 let doc = doc.as_ref().unwrap();
488 let subscription = doc
489 .observe_update_v1(move |_, e| {
490 let bytes = &e.update;
491 let len = bytes.len() as u32;
492 cb(state.0, len, bytes.as_ptr() as *const c_char)
493 })
494 .unwrap();
495 Box::into_raw(Box::new(subscription))
496}
497
498#[no_mangle]
499pub unsafe extern "C" fn ydoc_observe_updates_v2(
500 doc: *mut Doc,
501 state: *mut c_void,
502 cb: extern "C" fn(*mut c_void, u32, *const c_char),
503) -> *mut Subscription {
504 let state = CallbackState::new(state);
505 let doc = doc.as_ref().unwrap();
506 let subscription = doc
507 .observe_update_v2(move |_, e| {
508 let bytes = &e.update;
509 let len = bytes.len() as u32;
510 cb(state.0, len, bytes.as_ptr() as *const c_char)
511 })
512 .unwrap();
513 Box::into_raw(Box::new(subscription))
514}
515
516#[no_mangle]
517pub unsafe extern "C" fn ydoc_observe_after_transaction(
518 doc: *mut Doc,
519 state: *mut c_void,
520 cb: extern "C" fn(*mut c_void, *mut YAfterTransactionEvent),
521) -> *mut Subscription {
522 let state = CallbackState::new(state);
523 let doc = doc.as_ref().unwrap();
524 let subscription = doc
525 .observe_transaction_cleanup(move |_, e| {
526 let mut event = YAfterTransactionEvent::new(e);
527 cb(state.0, (&mut event) as *mut _);
528 })
529 .unwrap();
530 Box::into_raw(Box::new(subscription))
531}
532
533#[no_mangle]
534pub unsafe extern "C" fn ydoc_observe_subdocs(
535 doc: *mut Doc,
536 state: *mut c_void,
537 cb: extern "C" fn(*mut c_void, *mut YSubdocsEvent),
538) -> *mut Subscription {
539 let state = CallbackState::new(state);
540 let doc = doc.as_mut().unwrap();
541 let subscription = doc
542 .observe_subdocs(move |_, e| {
543 let mut event = YSubdocsEvent::new(e);
544 cb(state.0, (&mut event) as *mut _);
545 })
546 .unwrap();
547 Box::into_raw(Box::new(subscription))
548}
549
550#[no_mangle]
551pub unsafe extern "C" fn ydoc_observe_clear(
552 doc: *mut Doc,
553 state: *mut c_void,
554 cb: extern "C" fn(*mut c_void, *mut Doc),
555) -> *mut Subscription {
556 let state = CallbackState::new(state);
557 let doc = doc.as_mut().unwrap();
558 let subscription = doc
559 .observe_destroy(move |_, e| cb(state.0, e as *const Doc as *mut _))
560 .unwrap();
561 Box::into_raw(Box::new(subscription))
562}
563
564#[no_mangle]
566pub unsafe extern "C" fn ydoc_load(doc: *mut Doc, parent_txn: *mut Transaction) {
567 let doc = doc.as_ref().unwrap();
568 let txn = parent_txn.as_mut().unwrap();
569 if let Some(txn) = txn.as_mut() {
570 doc.load(txn)
571 } else {
572 panic!("ydoc_load: passed read-only parent transaction, where read-write one was expected")
573 }
574}
575
576#[no_mangle]
579pub unsafe extern "C" fn ydoc_clear(doc: *mut Doc, parent_txn: *mut Transaction) {
580 let doc = doc.as_mut().unwrap();
581 let txn = parent_txn.as_mut().unwrap();
582 if let Some(txn) = txn.as_mut() {
583 doc.destroy(txn)
584 } else {
585 panic!("ydoc_clear: passed read-only parent transaction, where read-write one was expected")
586 }
587}
588
589#[no_mangle]
596pub unsafe extern "C" fn ydoc_read_transaction(doc: *mut Doc) -> *mut Transaction {
597 assert!(!doc.is_null());
598
599 let doc = doc.as_mut().unwrap();
600 if let Ok(txn) = doc.try_transact() {
601 Box::into_raw(Box::new(Transaction::read_only(txn)))
602 } else {
603 null_mut()
604 }
605}
606
607#[no_mangle]
619pub unsafe extern "C" fn ydoc_write_transaction(
620 doc: *mut Doc,
621 origin_len: u32,
622 origin: *const c_char,
623) -> *mut Transaction {
624 assert!(!doc.is_null());
625
626 let doc = doc.as_mut().unwrap();
627 if origin_len == 0 {
628 if let Ok(txn) = doc.try_transact_mut() {
629 Box::into_raw(Box::new(Transaction::read_write(txn)))
630 } else {
631 null_mut()
632 }
633 } else {
634 let origin = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
635 if let Ok(txn) = doc.try_transact_mut_with(origin) {
636 Box::into_raw(Box::new(Transaction::read_write(txn)))
637 } else {
638 null_mut()
639 }
640 }
641}
642
643#[no_mangle]
645pub unsafe extern "C" fn ytransaction_subdocs(
646 txn: *mut Transaction,
647 len: *mut u32,
648) -> *mut *mut Doc {
649 let txn = txn.as_ref().unwrap();
650 let subdocs: Vec<_> = txn
651 .subdocs()
652 .map(|doc| doc as *const Doc as *mut Doc)
653 .collect();
654 let out = subdocs.into_boxed_slice();
655 *len = out.len() as u32;
656 Box::into_raw(out) as *mut _
657}
658
659#[no_mangle]
663pub unsafe extern "C" fn ytransaction_commit(txn: *mut Transaction) {
664 assert!(!txn.is_null());
665 drop(Box::from_raw(txn)); }
667
668#[no_mangle]
672pub unsafe extern "C" fn ytransaction_force_gc(txn: *mut Transaction) {
673 assert!(!txn.is_null());
674 let txn = txn.as_mut().unwrap();
675 let txn = txn.as_mut().unwrap();
676 txn.force_gc();
677}
678
679#[no_mangle]
682pub unsafe extern "C" fn ytransaction_writeable(txn: *mut Transaction) -> u8 {
683 assert!(!txn.is_null());
684 if txn.as_ref().unwrap().is_writeable() {
685 1
686 } else {
687 0
688 }
689}
690
691#[no_mangle]
697pub unsafe extern "C" fn ytype_get(txn: *mut Transaction, name: *const c_char) -> *mut Branch {
698 assert!(!txn.is_null());
699 assert!(!name.is_null());
700
701 let name = CStr::from_ptr(name).to_str().unwrap();
702 if let Some(txt) = txn.as_mut().unwrap().get_text(name) {
705 txt.into_raw_branch()
706 } else {
707 null_mut()
708 }
709}
710
711#[no_mangle]
715pub unsafe extern "C" fn ytext(doc: *mut Doc, name: *const c_char) -> *mut Branch {
716 assert!(!doc.is_null());
717 assert!(!name.is_null());
718
719 let name = CStr::from_ptr(name).to_str().unwrap();
720 let txt = doc.as_mut().unwrap().get_or_insert_text(name);
721 txt.into_raw_branch()
722}
723
724#[no_mangle]
732pub unsafe extern "C" fn yarray(doc: *mut Doc, name: *const c_char) -> *mut Branch {
733 assert!(!doc.is_null());
734 assert!(!name.is_null());
735
736 let name = CStr::from_ptr(name).to_str().unwrap();
737 doc.as_mut()
738 .unwrap()
739 .get_or_insert_array(name)
740 .into_raw_branch()
741}
742
743#[no_mangle]
751pub unsafe extern "C" fn ymap(doc: *mut Doc, name: *const c_char) -> *mut Branch {
752 assert!(!doc.is_null());
753 assert!(!name.is_null());
754
755 let name = CStr::from_ptr(name).to_str().unwrap();
756 doc.as_mut()
757 .unwrap()
758 .get_or_insert_map(name)
759 .into_raw_branch()
760}
761
762#[no_mangle]
766pub unsafe extern "C" fn yxmlfragment(doc: *mut Doc, name: *const c_char) -> *mut Branch {
767 assert!(!doc.is_null());
768 assert!(!name.is_null());
769
770 let name = CStr::from_ptr(name).to_str().unwrap();
771 doc.as_mut()
772 .unwrap()
773 .get_or_insert_xml_fragment(name)
774 .into_raw_branch()
775}
776
777#[no_mangle]
787pub unsafe extern "C" fn ytransaction_state_vector_v1(
788 txn: *const Transaction,
789 len: *mut u32,
790) -> *mut c_char {
791 assert!(!txn.is_null());
792
793 let txn = txn.as_ref().unwrap();
794 let state_vector = txn.state_vector();
795 let binary = state_vector.encode_v1().into_boxed_slice();
796
797 *len = binary.len() as u32;
798 Box::into_raw(binary) as *mut c_char
799}
800
801#[no_mangle]
816pub unsafe extern "C" fn ytransaction_state_diff_v1(
817 txn: *const Transaction,
818 sv: *const c_char,
819 sv_len: u32,
820 len: *mut u32,
821) -> *mut c_char {
822 assert!(!txn.is_null());
823
824 let txn = txn.as_ref().unwrap();
825 let sv = {
826 if sv.is_null() {
827 StateVector::default()
828 } else {
829 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
830 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
831 sv
832 } else {
833 return null_mut();
834 }
835 }
836 };
837
838 let mut encoder = EncoderV1::new();
839 txn.encode_diff(&sv, &mut encoder);
840 let binary = encoder.to_vec().into_boxed_slice();
841 *len = binary.len() as u32;
842 Box::into_raw(binary) as *mut c_char
843}
844
845#[no_mangle]
860pub unsafe extern "C" fn ytransaction_state_diff_v2(
861 txn: *const Transaction,
862 sv: *const c_char,
863 sv_len: u32,
864 len: *mut u32,
865) -> *mut c_char {
866 assert!(!txn.is_null());
867
868 let txn = txn.as_ref().unwrap();
869 let sv = {
870 if sv.is_null() {
871 StateVector::default()
872 } else {
873 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
874 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
875 sv
876 } else {
877 return null_mut();
878 }
879 }
880 };
881
882 let mut encoder = EncoderV2::new();
883 txn.encode_diff(&sv, &mut encoder);
884 let binary = encoder.to_vec().into_boxed_slice();
885 *len = binary.len() as u32;
886 Box::into_raw(binary) as *mut c_char
887}
888
889#[no_mangle]
893pub unsafe extern "C" fn ytransaction_snapshot(
894 txn: *const Transaction,
895 len: *mut u32,
896) -> *mut c_char {
897 assert!(!txn.is_null());
898 let txn = txn.as_ref().unwrap();
899 let binary = txn.snapshot().encode_v1().into_boxed_slice();
900
901 *len = binary.len() as u32;
902 Box::into_raw(binary) as *mut c_char
903}
904
905#[no_mangle]
914pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v1(
915 txn: *const Transaction,
916 snapshot: *const c_char,
917 snapshot_len: u32,
918 len: *mut u32,
919) -> *mut c_char {
920 assert!(!txn.is_null());
921 let txn = txn.as_ref().unwrap();
922 let snapshot = {
923 let len = snapshot_len as usize;
924 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
925 Snapshot::decode_v1(&data).unwrap()
926 };
927 let mut encoder = EncoderV1::new();
928 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
929 Err(_) => null_mut(),
930 Ok(_) => {
931 let binary = encoder.to_vec().into_boxed_slice();
932 *len = binary.len() as u32;
933 Box::into_raw(binary) as *mut c_char
934 }
935 }
936}
937
938#[no_mangle]
947pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v2(
948 txn: *const Transaction,
949 snapshot: *const c_char,
950 snapshot_len: u32,
951 len: *mut u32,
952) -> *mut c_char {
953 assert!(!txn.is_null());
954 let txn = txn.as_ref().unwrap();
955 let snapshot = {
956 let len = snapshot_len as usize;
957 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
958 Snapshot::decode_v1(&data).unwrap()
959 };
960 let mut encoder = EncoderV2::new();
961 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
962 Err(_) => null_mut(),
963 Ok(_) => {
964 let binary = encoder.to_vec().into_boxed_slice();
965 *len = binary.len() as u32;
966 Box::into_raw(binary) as *mut c_char
967 }
968 }
969}
970
971#[no_mangle]
977pub unsafe extern "C" fn ytransaction_pending_ds(txn: *const Transaction) -> *mut YDeleteSet {
978 let txn = txn.as_ref().unwrap();
979 match txn.store().pending_ds() {
980 None => null_mut(),
981 Some(ds) => Box::into_raw(Box::new(YDeleteSet::new(ds))),
982 }
983}
984
985#[no_mangle]
986pub unsafe extern "C" fn ydelete_set_destroy(ds: *mut YDeleteSet) {
987 if ds.is_null() {
988 return;
989 }
990 drop(Box::from_raw(ds))
991}
992
993#[no_mangle]
1002pub unsafe extern "C" fn ytransaction_pending_update(
1003 txn: *const Transaction,
1004) -> *mut YPendingUpdate {
1005 let txn = txn.as_ref().unwrap();
1006 match txn.store().pending_update() {
1007 None => null_mut(),
1008 Some(u) => {
1009 let binary = u.update.encode_v1().into_boxed_slice();
1010 let update_len = binary.len() as u32;
1011 let missing = YStateVector::new(&u.missing);
1012 let update = YPendingUpdate {
1013 missing,
1014 update_len,
1015 update_v1: Box::into_raw(binary) as *mut c_char,
1016 };
1017 Box::into_raw(Box::new(update))
1018 }
1019 }
1020}
1021
1022#[repr(C)]
1026pub struct YPendingUpdate {
1027 pub missing: YStateVector,
1030 pub update_v1: *mut c_char,
1032 pub update_len: u32,
1034}
1035
1036#[no_mangle]
1037pub unsafe extern "C" fn ypending_update_destroy(update: *mut YPendingUpdate) {
1038 if update.is_null() {
1039 return;
1040 }
1041 let update = Box::from_raw(update);
1042 drop(update.missing);
1043 ybinary_destroy(update.update_v1, update.update_len);
1044}
1045
1046#[no_mangle]
1050pub unsafe extern "C" fn yupdate_debug_v1(update: *const c_char, update_len: u32) -> *mut c_char {
1051 assert!(!update.is_null());
1052
1053 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1054 if let Ok(u) = Update::decode_v1(data) {
1055 let str = format!("{:#?}", u);
1056 CString::new(str).unwrap().into_raw()
1057 } else {
1058 null_mut()
1059 }
1060}
1061
1062#[no_mangle]
1066pub unsafe extern "C" fn yupdate_debug_v2(update: *const c_char, update_len: u32) -> *mut c_char {
1067 assert!(!update.is_null());
1068
1069 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1070 if let Ok(u) = Update::decode_v2(data) {
1071 let str = format!("{:#?}", u);
1072 CString::new(str).unwrap().into_raw()
1073 } else {
1074 null_mut()
1075 }
1076}
1077
1078#[no_mangle]
1092pub unsafe extern "C" fn ytransaction_apply(
1093 txn: *mut Transaction,
1094 diff: *const c_char,
1095 diff_len: u32,
1096) -> u8 {
1097 assert!(!txn.is_null());
1098 assert!(!diff.is_null());
1099
1100 let update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1101 let mut decoder = DecoderV1::from(update);
1102 match Update::decode(&mut decoder) {
1103 Ok(update) => {
1104 let txn = txn.as_mut().unwrap();
1105 let txn = txn
1106 .as_mut()
1107 .expect("provided transaction was not writeable");
1108 match txn.apply_update(update) {
1109 Ok(_) => 0,
1110 Err(e) => update_err_code(e),
1111 }
1112 }
1113 Err(e) => err_code(e),
1114 }
1115}
1116
1117#[no_mangle]
1131pub unsafe extern "C" fn ytransaction_apply_v2(
1132 txn: *mut Transaction,
1133 diff: *const c_char,
1134 diff_len: u32,
1135) -> u8 {
1136 assert!(!txn.is_null());
1137 assert!(!diff.is_null());
1138
1139 let mut update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1140 match Update::decode_v2(&mut update) {
1141 Ok(update) => {
1142 let txn = txn.as_mut().unwrap();
1143 let txn = txn
1144 .as_mut()
1145 .expect("provided transaction was not writeable");
1146 match txn.apply_update(update) {
1147 Ok(_) => 0,
1148 Err(e) => update_err_code(e),
1149 }
1150 }
1151 Err(e) => err_code(e),
1152 }
1153}
1154
1155pub const ERR_CODE_IO: u8 = 1;
1157
1158pub const ERR_CODE_VAR_INT: u8 = 2;
1160
1161pub const ERR_CODE_EOS: u8 = 3;
1163
1164pub const ERR_CODE_UNEXPECTED_VALUE: u8 = 4;
1166
1167pub const ERR_CODE_INVALID_JSON: u8 = 5;
1169
1170pub const ERR_CODE_OTHER: u8 = 6;
1172
1173pub const ERR_NOT_ENOUGH_MEMORY: u8 = 7;
1175
1176pub const ERR_TYPE_MISMATCH: u8 = 8;
1178
1179pub const ERR_CUSTOM: u8 = 9;
1181
1182pub const ERR_INVALID_PARENT: u8 = 9;
1184
1185fn err_code(e: Error) -> u8 {
1186 match e {
1187 Error::InvalidVarInt => ERR_CODE_VAR_INT,
1188 Error::EndOfBuffer(_) => ERR_CODE_EOS,
1189 Error::UnexpectedValue => ERR_CODE_UNEXPECTED_VALUE,
1190 Error::InvalidJSON(_) => ERR_CODE_INVALID_JSON,
1191 Error::NotEnoughMemory(_) => ERR_NOT_ENOUGH_MEMORY,
1192 Error::TypeMismatch(_) => ERR_TYPE_MISMATCH,
1193 Error::Custom(_) => ERR_CUSTOM,
1194 }
1195}
1196fn update_err_code(e: UpdateError) -> u8 {
1197 match e {
1198 UpdateError::InvalidParent(_, _) => ERR_INVALID_PARENT,
1199 }
1200}
1201
1202#[no_mangle]
1204pub unsafe extern "C" fn ytext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
1205 assert!(!txt.is_null());
1206 let txn = txn.as_ref().unwrap();
1207 let txt = TextRef::from_raw_branch(txt);
1208 txt.len(txn)
1209}
1210
1211#[no_mangle]
1215pub unsafe extern "C" fn ytext_string(txt: *const Branch, txn: *const Transaction) -> *mut c_char {
1216 assert!(!txt.is_null());
1217
1218 let txn = txn.as_ref().unwrap();
1219 let txt = TextRef::from_raw_branch(txt);
1220 let str = txt.get_string(txn);
1221 CString::new(str).unwrap().into_raw()
1222}
1223
1224#[no_mangle]
1235pub unsafe extern "C" fn ytext_insert(
1236 txt: *const Branch,
1237 txn: *mut Transaction,
1238 index: u32,
1239 value: *const c_char,
1240 attrs: *const YInput,
1241) {
1242 assert!(!txt.is_null());
1243 assert!(!txn.is_null());
1244 assert!(!value.is_null());
1245
1246 let chunk = CStr::from_ptr(value).to_str().unwrap();
1247 let txn = txn.as_mut().unwrap();
1248 let txn = txn
1249 .as_mut()
1250 .expect("provided transaction was not writeable");
1251 let txt = TextRef::from_raw_branch(txt);
1252 let index = index as u32;
1253 if attrs.is_null() {
1254 txt.insert(txn, index, chunk)
1255 } else {
1256 if let Some(attrs) = map_attrs(attrs.read().into()) {
1257 txt.insert_with_attributes(txn, index, chunk, attrs)
1258 } else {
1259 panic!("ytext_insert: passed attributes are not of map type")
1260 }
1261 }
1262}
1263
1264#[no_mangle]
1267pub unsafe extern "C" fn ytext_format(
1268 txt: *const Branch,
1269 txn: *mut Transaction,
1270 index: u32,
1271 len: u32,
1272 attrs: *const YInput,
1273) {
1274 assert!(!txt.is_null());
1275 assert!(!txn.is_null());
1276 assert!(!attrs.is_null());
1277
1278 if let Some(attrs) = map_attrs(attrs.read().into()) {
1279 let txt = TextRef::from_raw_branch(txt);
1280 let txn = txn.as_mut().unwrap();
1281 let txn = txn
1282 .as_mut()
1283 .expect("provided transaction was not writeable");
1284 let index = index as u32;
1285 let len = len as u32;
1286 txt.format(txn, index, len, attrs);
1287 } else {
1288 panic!("ytext_format: passed attributes are not of map type")
1289 }
1290}
1291
1292#[no_mangle]
1303pub unsafe extern "C" fn ytext_insert_embed(
1304 txt: *const Branch,
1305 txn: *mut Transaction,
1306 index: u32,
1307 content: *const YInput,
1308 attrs: *const YInput,
1309) {
1310 assert!(!txt.is_null());
1311 assert!(!txn.is_null());
1312 assert!(!content.is_null());
1313
1314 let txn = txn.as_mut().unwrap();
1315 let txn = txn
1316 .as_mut()
1317 .expect("provided transaction was not writeable");
1318 let txt = TextRef::from_raw_branch(txt);
1319 let index = index as u32;
1320 let content = content.read();
1321 if attrs.is_null() {
1322 txt.insert_embed(txn, index, content);
1323 } else {
1324 if let Some(attrs) = map_attrs(attrs.read().into()) {
1325 txt.insert_embed_with_attributes(txn, index, content, attrs);
1326 } else {
1327 panic!("ytext_insert_embed: passed attributes are not of map type")
1328 }
1329 }
1330}
1331
1332#[no_mangle]
1346pub unsafe extern "C" fn ytext_insert_delta(
1347 txt: *const Branch,
1348 txn: *mut Transaction,
1349 delta: *mut YDeltaIn,
1350 delta_len: u32,
1351) {
1352 let txt = TextRef::from_raw_branch(txt);
1353 let txn = txn.as_mut().unwrap();
1354 let txn = txn
1355 .as_mut()
1356 .expect("provided transaction was not writeable");
1357 let delta = std::slice::from_raw_parts(delta, delta_len as usize);
1358 let mut insert = Vec::with_capacity(delta.len());
1359 for chunk in delta {
1360 let d = chunk.as_input();
1361 insert.push(d);
1362 }
1363 txt.apply_delta(txn, insert);
1364}
1365
1366#[no_mangle]
1370pub unsafe extern "C" fn ydelta_input_retain(len: u32, attrs: *const YInput) -> YDeltaIn {
1371 YDeltaIn {
1372 tag: Y_EVENT_CHANGE_RETAIN,
1373 len,
1374 attributes: attrs,
1375 insert: null(),
1376 }
1377}
1378
1379#[no_mangle]
1382pub unsafe extern "C" fn ydelta_input_delete(len: u32) -> YDeltaIn {
1383 YDeltaIn {
1384 tag: Y_EVENT_CHANGE_DELETE,
1385 len,
1386 attributes: null(),
1387 insert: null(),
1388 }
1389}
1390
1391#[no_mangle]
1397pub unsafe extern "C" fn ydelta_input_insert(
1398 data: *const YInput,
1399 attrs: *const YInput,
1400) -> YDeltaIn {
1401 YDeltaIn {
1402 tag: Y_EVENT_CHANGE_ADD,
1403 len: 1,
1404 attributes: attrs,
1405 insert: data,
1406 }
1407}
1408
1409fn map_attrs(attrs: Any) -> Option<Attrs> {
1410 if let Any::Map(attrs) = attrs {
1411 let attrs = attrs
1412 .iter()
1413 .map(|(k, v)| (k.as_str().into(), v.clone()))
1414 .collect();
1415 Some(attrs)
1416 } else {
1417 None
1418 }
1419}
1420
1421#[no_mangle]
1430pub unsafe extern "C" fn ytext_remove_range(
1431 txt: *const Branch,
1432 txn: *mut Transaction,
1433 index: u32,
1434 length: u32,
1435) {
1436 assert!(!txt.is_null());
1437 assert!(!txn.is_null());
1438
1439 let txn = txn.as_mut().unwrap();
1440 let txn = txn
1441 .as_mut()
1442 .expect("provided transaction was not writeable");
1443 let txt = TextRef::from_raw_branch(txt);
1444 txt.remove_range(txn, index as u32, length as u32)
1445}
1446
1447#[no_mangle]
1449pub unsafe extern "C" fn yarray_len(array: *const Branch) -> u32 {
1450 assert!(!array.is_null());
1451
1452 let array = array.as_ref().unwrap();
1453 array.len() as u32
1454}
1455
1456#[no_mangle]
1461pub unsafe extern "C" fn yarray_get(
1462 array: *const Branch,
1463 txn: *const Transaction,
1464 index: u32,
1465) -> *mut YOutput {
1466 assert!(!array.is_null());
1467
1468 let array = ArrayRef::from_raw_branch(array);
1469 let txn = txn.as_ref().unwrap();
1470
1471 if let Some(val) = array.get(txn, index as u32) {
1472 Box::into_raw(Box::new(YOutput::from(val)))
1473 } else {
1474 std::ptr::null_mut()
1475 }
1476}
1477
1478#[no_mangle]
1489pub unsafe extern "C" fn yarray_get_json(
1490 array: *const Branch,
1491 txn: *const Transaction,
1492 index: u32,
1493) -> *mut c_char {
1494 assert!(!array.is_null());
1495
1496 let array = ArrayRef::from_raw_branch(array);
1497 let txn = txn.as_ref().unwrap();
1498
1499 if let Some(val) = array.get(txn, index as u32) {
1500 let any = val.to_json(txn);
1501 let json = match serde_json::to_string(&any) {
1502 Ok(json) => json,
1503 Err(_) => return std::ptr::null_mut(),
1504 };
1505 CString::new(json).unwrap().into_raw()
1506 } else {
1507 std::ptr::null_mut()
1508 }
1509}
1510
1511#[no_mangle]
1522pub unsafe extern "C" fn yarray_insert_range(
1523 array: *const Branch,
1524 txn: *mut Transaction,
1525 index: u32,
1526 items: *const YInput,
1527 items_len: u32,
1528) {
1529 assert!(!array.is_null());
1530 assert!(!txn.is_null());
1531 assert!(!items.is_null());
1532
1533 let array = ArrayRef::from_raw_branch(array);
1534 let txn = txn.as_mut().unwrap();
1535 let txn = txn
1536 .as_mut()
1537 .expect("provided transaction was not writeable");
1538
1539 let ptr = items;
1540 let mut i = 0;
1541 let mut j = index as u32;
1542 let len = items_len as isize;
1543 while i < len {
1544 let mut vec: Vec<Any> = Vec::default();
1545
1546 while i < len {
1548 let val = ptr.offset(i).read();
1549 if val.tag <= 0 {
1550 let any = val.into();
1551 vec.push(any);
1552 } else {
1553 break;
1554 }
1555 i += 1;
1556 }
1557
1558 if !vec.is_empty() {
1559 let len = vec.len() as u32;
1560 array.insert_range(txn, j, vec);
1561 j += len;
1562 } else {
1563 let val = ptr.offset(i).read();
1564 array.insert(txn, j, val);
1565 i += 1;
1566 j += 1;
1567 }
1568 }
1569}
1570
1571#[no_mangle]
1575pub unsafe extern "C" fn yarray_remove_range(
1576 array: *const Branch,
1577 txn: *mut Transaction,
1578 index: u32,
1579 len: u32,
1580) {
1581 assert!(!array.is_null());
1582 assert!(!txn.is_null());
1583
1584 let array = ArrayRef::from_raw_branch(array);
1585 let txn = txn.as_mut().unwrap();
1586 let txn = txn
1587 .as_mut()
1588 .expect("provided transaction was not writeable");
1589
1590 array.remove_range(txn, index as u32, len as u32)
1591}
1592
1593#[no_mangle]
1594pub unsafe extern "C" fn yarray_move(
1595 array: *const Branch,
1596 txn: *mut Transaction,
1597 source: u32,
1598 target: u32,
1599) {
1600 assert!(!array.is_null());
1601 assert!(!txn.is_null());
1602
1603 let array = ArrayRef::from_raw_branch(array);
1604 let txn = txn.as_mut().unwrap();
1605 let txn = txn
1606 .as_mut()
1607 .expect("provided transaction was not writeable");
1608
1609 array.move_to(txn, source as u32, target as u32)
1610}
1611
1612#[no_mangle]
1618pub unsafe extern "C" fn yarray_iter(
1619 array: *const Branch,
1620 txn: *mut Transaction,
1621) -> *mut ArrayIter {
1622 assert!(!array.is_null());
1623 assert!(!txn.is_null());
1624
1625 let txn = txn.as_ref().unwrap();
1626 let array = &ArrayRef::from_raw_branch(array) as *const ArrayRef;
1627 Box::into_raw(Box::new(ArrayIter(array.as_ref().unwrap().iter(txn))))
1628}
1629
1630#[no_mangle]
1632pub unsafe extern "C" fn yarray_iter_destroy(iter: *mut ArrayIter) {
1633 if !iter.is_null() {
1634 drop(Box::from_raw(iter))
1635 }
1636}
1637
1638#[no_mangle]
1643pub unsafe extern "C" fn yarray_iter_next(iterator: *mut ArrayIter) -> *mut YOutput {
1644 assert!(!iterator.is_null());
1645
1646 let iter = iterator.as_mut().unwrap();
1647 if let Some(v) = iter.0.next() {
1648 let out = YOutput::from(v);
1649 Box::into_raw(Box::new(out))
1650 } else {
1651 std::ptr::null_mut()
1652 }
1653}
1654
1655#[no_mangle]
1660pub unsafe extern "C" fn ymap_iter(map: *const Branch, txn: *const Transaction) -> *mut MapIter {
1661 assert!(!map.is_null());
1662
1663 let txn = txn.as_ref().unwrap();
1664 let map = &MapRef::from_raw_branch(map) as *const MapRef;
1665 Box::into_raw(Box::new(MapIter(map.as_ref().unwrap().iter(txn))))
1666}
1667
1668#[no_mangle]
1670pub unsafe extern "C" fn ymap_iter_destroy(iter: *mut MapIter) {
1671 if !iter.is_null() {
1672 drop(Box::from_raw(iter))
1673 }
1674}
1675
1676#[no_mangle]
1682pub unsafe extern "C" fn ymap_iter_next(iter: *mut MapIter) -> *mut YMapEntry {
1683 assert!(!iter.is_null());
1684
1685 let iter = iter.as_mut().unwrap();
1686 if let Some((key, value)) = iter.0.next() {
1687 let output = YOutput::from(value);
1688 Box::into_raw(Box::new(YMapEntry::new(key, Box::new(output))))
1689 } else {
1690 std::ptr::null_mut()
1691 }
1692}
1693
1694#[no_mangle]
1696pub unsafe extern "C" fn ymap_len(map: *const Branch, txn: *const Transaction) -> u32 {
1697 assert!(!map.is_null());
1698
1699 let txn = txn.as_ref().unwrap();
1700 let map = MapRef::from_raw_branch(map);
1701
1702 map.len(txn)
1703}
1704
1705#[no_mangle]
1714pub unsafe extern "C" fn ymap_insert(
1715 map: *const Branch,
1716 txn: *mut Transaction,
1717 key: *const c_char,
1718 value: *const YInput,
1719) {
1720 assert!(!map.is_null());
1721 assert!(!txn.is_null());
1722 assert!(!key.is_null());
1723 assert!(!value.is_null());
1724
1725 let cstr = CStr::from_ptr(key);
1726 let key = cstr.to_str().unwrap().to_string();
1727
1728 let map = MapRef::from_raw_branch(map);
1729 let txn = txn.as_mut().unwrap();
1730 let txn = txn
1731 .as_mut()
1732 .expect("provided transaction was not writeable");
1733
1734 map.insert(txn, key, value.read());
1735}
1736
1737#[no_mangle]
1742pub unsafe extern "C" fn ymap_remove(
1743 map: *const Branch,
1744 txn: *mut Transaction,
1745 key: *const c_char,
1746) -> u8 {
1747 assert!(!map.is_null());
1748 assert!(!txn.is_null());
1749 assert!(!key.is_null());
1750
1751 let key = CStr::from_ptr(key).to_str().unwrap();
1752
1753 let map = MapRef::from_raw_branch(map);
1754 let txn = txn.as_mut().unwrap();
1755 let txn = txn
1756 .as_mut()
1757 .expect("provided transaction was not writeable");
1758
1759 if let Some(_) = map.remove(txn, key) {
1760 Y_TRUE
1761 } else {
1762 Y_FALSE
1763 }
1764}
1765
1766#[no_mangle]
1772pub unsafe extern "C" fn ymap_get(
1773 map: *const Branch,
1774 txn: *const Transaction,
1775 key: *const c_char,
1776) -> *mut YOutput {
1777 assert!(!map.is_null());
1778 assert!(!key.is_null());
1779 assert!(!txn.is_null());
1780
1781 let txn = txn.as_ref().unwrap();
1782 let key = CStr::from_ptr(key).to_str().unwrap();
1783
1784 let map = MapRef::from_raw_branch(map);
1785
1786 if let Some(value) = map.get(txn, key) {
1787 let output = YOutput::from(value);
1788 Box::into_raw(Box::new(output))
1789 } else {
1790 std::ptr::null_mut()
1791 }
1792}
1793
1794#[no_mangle]
1803pub unsafe extern "C" fn ymap_get_json(
1804 map: *const Branch,
1805 txn: *const Transaction,
1806 key: *const c_char,
1807) -> *mut c_char {
1808 assert!(!map.is_null());
1809 assert!(!key.is_null());
1810 assert!(!txn.is_null());
1811
1812 let txn = txn.as_ref().unwrap();
1813 let key = CStr::from_ptr(key).to_str().unwrap();
1814
1815 let map = MapRef::from_raw_branch(map);
1816
1817 if let Some(value) = map.get(txn, key) {
1818 let any = value.to_json(txn);
1819 match serde_json::to_string(&any) {
1820 Ok(json) => CString::new(json).unwrap().into_raw(),
1821 Err(_) => std::ptr::null_mut(),
1822 }
1823 } else {
1824 std::ptr::null_mut()
1825 }
1826}
1827
1828#[no_mangle]
1830pub unsafe extern "C" fn ymap_remove_all(map: *const Branch, txn: *mut Transaction) {
1831 assert!(!map.is_null());
1832 assert!(!txn.is_null());
1833
1834 let map = MapRef::from_raw_branch(map);
1835 let txn = txn.as_mut().unwrap();
1836 let txn = txn
1837 .as_mut()
1838 .expect("provided transaction was not writeable");
1839
1840 map.clear(txn);
1841}
1842
1843#[no_mangle]
1849pub unsafe extern "C" fn yxmlelem_tag(xml: *const Branch) -> *mut c_char {
1850 assert!(!xml.is_null());
1851 let xml = XmlElementRef::from_raw_branch(xml);
1852 if let Some(tag) = xml.try_tag() {
1853 CString::new(tag.deref()).unwrap().into_raw()
1854 } else {
1855 null_mut()
1856 }
1857}
1858
1859#[no_mangle]
1865pub unsafe extern "C" fn yxmlelem_string(
1866 xml: *const Branch,
1867 txn: *const Transaction,
1868) -> *mut c_char {
1869 assert!(!xml.is_null());
1870 assert!(!txn.is_null());
1871
1872 let txn = txn.as_ref().unwrap();
1873 let xml = XmlElementRef::from_raw_branch(xml);
1874
1875 let str = xml.get_string(txn);
1876 CString::new(str).unwrap().into_raw()
1877}
1878
1879#[no_mangle]
1885pub unsafe extern "C" fn yxmlelem_insert_attr(
1886 xml: *const Branch,
1887 txn: *mut Transaction,
1888 attr_name: *const c_char,
1889 attr_value: *const c_char,
1890) {
1891 assert!(!xml.is_null());
1892 assert!(!txn.is_null());
1893 assert!(!attr_name.is_null());
1894 assert!(!attr_value.is_null());
1895
1896 let xml = XmlElementRef::from_raw_branch(xml);
1897 let txn = txn.as_mut().unwrap();
1898 let txn = txn
1899 .as_mut()
1900 .expect("provided transaction was not writeable");
1901
1902 let key = CStr::from_ptr(attr_name).to_str().unwrap();
1903 let value = CStr::from_ptr(attr_value).to_str().unwrap();
1904
1905 xml.insert_attribute(txn, key, value);
1906}
1907
1908#[no_mangle]
1912pub unsafe extern "C" fn yxmlelem_remove_attr(
1913 xml: *const Branch,
1914 txn: *mut Transaction,
1915 attr_name: *const c_char,
1916) {
1917 assert!(!xml.is_null());
1918 assert!(!txn.is_null());
1919 assert!(!attr_name.is_null());
1920
1921 let xml = XmlElementRef::from_raw_branch(xml);
1922 let txn = txn.as_mut().unwrap();
1923 let txn = txn
1924 .as_mut()
1925 .expect("provided transaction was not writeable");
1926
1927 let key = CStr::from_ptr(attr_name).to_str().unwrap();
1928 xml.remove_attribute(txn, &key);
1929}
1930
1931#[no_mangle]
1937pub unsafe extern "C" fn yxmlelem_get_attr(
1938 xml: *const Branch,
1939 txn: *const Transaction,
1940 attr_name: *const c_char,
1941) -> *mut c_char {
1942 assert!(!xml.is_null());
1943 assert!(!attr_name.is_null());
1944 assert!(!txn.is_null());
1945
1946 let xml = XmlElementRef::from_raw_branch(xml);
1947
1948 let key = CStr::from_ptr(attr_name).to_str().unwrap();
1949 let txn = txn.as_ref().unwrap();
1950 if let Some(value) = xml.get_attribute(txn, key) {
1951 CString::new(value).unwrap().into_raw()
1952 } else {
1953 std::ptr::null_mut()
1954 }
1955}
1956
1957#[no_mangle]
1962pub unsafe extern "C" fn yxmlelem_attr_iter(
1963 xml: *const Branch,
1964 txn: *const Transaction,
1965) -> *mut Attributes {
1966 assert!(!xml.is_null());
1967 assert!(!txn.is_null());
1968
1969 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
1970 let txn = txn.as_ref().unwrap();
1971 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
1972}
1973
1974#[no_mangle]
1979pub unsafe extern "C" fn yxmltext_attr_iter(
1980 xml: *const Branch,
1981 txn: *const Transaction,
1982) -> *mut Attributes {
1983 assert!(!xml.is_null());
1984 assert!(!txn.is_null());
1985
1986 let xml = &XmlTextRef::from_raw_branch(xml) as *const XmlTextRef;
1987 let txn = txn.as_ref().unwrap();
1988 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
1989}
1990
1991#[no_mangle]
1994pub unsafe extern "C" fn yxmlattr_iter_destroy(iterator: *mut Attributes) {
1995 if !iterator.is_null() {
1996 drop(Box::from_raw(iterator))
1997 }
1998}
1999
2000#[no_mangle]
2006pub unsafe extern "C" fn yxmlattr_iter_next(iterator: *mut Attributes) -> *mut YXmlAttr {
2007 assert!(!iterator.is_null());
2008
2009 let iter = iterator.as_mut().unwrap();
2010
2011 if let Some((name, value)) = iter.0.next() {
2012 Box::into_raw(Box::new(YXmlAttr {
2013 name: CString::new(name).unwrap().into_raw(),
2014 value: CString::new(value).unwrap().into_raw(),
2015 }))
2016 } else {
2017 std::ptr::null_mut()
2018 }
2019}
2020
2021#[no_mangle]
2029pub unsafe extern "C" fn yxml_next_sibling(
2030 xml: *const Branch,
2031 txn: *const Transaction,
2032) -> *mut YOutput {
2033 assert!(!xml.is_null());
2034 assert!(!txn.is_null());
2035
2036 let xml = XmlElementRef::from_raw_branch(xml);
2037 let txn = txn.as_ref().unwrap();
2038
2039 let mut siblings = xml.siblings(txn);
2040 if let Some(next) = siblings.next() {
2041 match next {
2042 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2043 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2044 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2045 }
2046 } else {
2047 null_mut()
2048 }
2049}
2050
2051#[no_mangle]
2057pub unsafe extern "C" fn yxml_prev_sibling(
2058 xml: *const Branch,
2059 txn: *const Transaction,
2060) -> *mut YOutput {
2061 assert!(!xml.is_null());
2062 assert!(!txn.is_null());
2063
2064 let xml = XmlElementRef::from_raw_branch(xml);
2065 let txn = txn.as_ref().unwrap();
2066
2067 let mut siblings = xml.siblings(txn);
2068 if let Some(next) = siblings.next_back() {
2069 match next {
2070 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2071 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2072 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2073 }
2074 } else {
2075 null_mut()
2076 }
2077}
2078
2079#[no_mangle]
2082pub unsafe extern "C" fn yxmlelem_parent(xml: *const Branch) -> *mut Branch {
2083 assert!(!xml.is_null());
2084
2085 let xml = XmlElementRef::from_raw_branch(xml);
2086
2087 if let Some(parent) = xml.parent() {
2088 let branch = parent.as_ptr();
2089 branch.deref() as *const Branch as *mut Branch
2090 } else {
2091 std::ptr::null_mut()
2092 }
2093}
2094
2095#[no_mangle]
2098pub unsafe extern "C" fn yxmlelem_child_len(xml: *const Branch, txn: *const Transaction) -> u32 {
2099 assert!(!xml.is_null());
2100 assert!(!txn.is_null());
2101
2102 let txn = txn.as_ref().unwrap();
2103 let xml = XmlElementRef::from_raw_branch(xml);
2104
2105 xml.len(txn) as u32
2106}
2107
2108#[no_mangle]
2113pub unsafe extern "C" fn yxmlelem_first_child(xml: *const Branch) -> *mut YOutput {
2114 assert!(!xml.is_null());
2115
2116 let xml = XmlElementRef::from_raw_branch(xml);
2117
2118 if let Some(value) = xml.first_child() {
2119 match value {
2120 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2121 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2122 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2123 }
2124 } else {
2125 std::ptr::null_mut()
2126 }
2127}
2128
2129#[no_mangle]
2135pub unsafe extern "C" fn yxmlelem_tree_walker(
2136 xml: *const Branch,
2137 txn: *const Transaction,
2138) -> *mut TreeWalker {
2139 assert!(!xml.is_null());
2140 assert!(!txn.is_null());
2141
2142 let txn = txn.as_ref().unwrap();
2143 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2144 Box::into_raw(Box::new(TreeWalker(xml.as_ref().unwrap().successors(txn))))
2145}
2146
2147#[no_mangle]
2149pub unsafe extern "C" fn yxmlelem_tree_walker_destroy(iter: *mut TreeWalker) {
2150 if !iter.is_null() {
2151 drop(Box::from_raw(iter))
2152 }
2153}
2154
2155#[no_mangle]
2160pub unsafe extern "C" fn yxmlelem_tree_walker_next(iterator: *mut TreeWalker) -> *mut YOutput {
2161 assert!(!iterator.is_null());
2162
2163 let iter = iterator.as_mut().unwrap();
2164
2165 if let Some(next) = iter.0.next() {
2166 match next {
2167 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2168 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2169 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2170 }
2171 } else {
2172 std::ptr::null_mut()
2173 }
2174}
2175
2176#[no_mangle]
2185pub unsafe extern "C" fn yxmlelem_insert_elem(
2186 xml: *const Branch,
2187 txn: *mut Transaction,
2188 index: u32,
2189 name: *const c_char,
2190) -> *mut Branch {
2191 assert!(!xml.is_null());
2192 assert!(!txn.is_null());
2193 assert!(!name.is_null());
2194
2195 let xml = XmlElementRef::from_raw_branch(xml);
2196 let txn = txn.as_mut().unwrap();
2197 let txn = txn
2198 .as_mut()
2199 .expect("provided transaction was not writeable");
2200
2201 let name = CStr::from_ptr(name).to_str().unwrap();
2202 xml.insert(txn, index as u32, XmlElementPrelim::empty(name))
2203 .into_raw_branch()
2204}
2205
2206#[no_mangle]
2212pub unsafe extern "C" fn yxmlelem_insert_text(
2213 xml: *const Branch,
2214 txn: *mut Transaction,
2215 index: u32,
2216) -> *mut Branch {
2217 assert!(!xml.is_null());
2218 assert!(!txn.is_null());
2219
2220 let xml = XmlElementRef::from_raw_branch(xml);
2221 let txn = txn.as_mut().unwrap();
2222 let txn = txn
2223 .as_mut()
2224 .expect("provided transaction was not writeable");
2225 xml.insert(txn, index as u32, XmlTextPrelim::new(""))
2226 .into_raw_branch()
2227}
2228
2229#[no_mangle]
2233pub unsafe extern "C" fn yxmlelem_remove_range(
2234 xml: *const Branch,
2235 txn: *mut Transaction,
2236 index: u32,
2237 len: u32,
2238) {
2239 assert!(!xml.is_null());
2240 assert!(!txn.is_null());
2241
2242 let xml = XmlElementRef::from_raw_branch(xml);
2243 let txn = txn.as_mut().unwrap();
2244 let txn = txn
2245 .as_mut()
2246 .expect("provided transaction was not writeable");
2247
2248 xml.remove_range(txn, index as u32, len as u32)
2249}
2250
2251#[no_mangle]
2257pub unsafe extern "C" fn yxmlelem_get(
2258 xml: *const Branch,
2259 txn: *const Transaction,
2260 index: u32,
2261) -> *const YOutput {
2262 assert!(!xml.is_null());
2263 assert!(!txn.is_null());
2264
2265 let xml = XmlElementRef::from_raw_branch(xml);
2266 let txn = txn.as_ref().unwrap();
2267
2268 if let Some(child) = xml.get(txn, index as u32) {
2269 match child {
2270 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2271 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2272 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2273 }
2274 } else {
2275 std::ptr::null()
2276 }
2277}
2278
2279#[no_mangle]
2282pub unsafe extern "C" fn yxmltext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
2283 assert!(!txt.is_null());
2284 assert!(!txn.is_null());
2285
2286 let txn = txn.as_ref().unwrap();
2287 let txt = XmlTextRef::from_raw_branch(txt);
2288
2289 txt.len(txn) as u32
2290}
2291
2292#[no_mangle]
2296pub unsafe extern "C" fn yxmltext_string(
2297 txt: *const Branch,
2298 txn: *const Transaction,
2299) -> *mut c_char {
2300 assert!(!txt.is_null());
2301 assert!(!txn.is_null());
2302
2303 let txn = txn.as_ref().unwrap();
2304 let txt = XmlTextRef::from_raw_branch(txt);
2305
2306 let str = txt.get_string(txn);
2307 CString::new(str).unwrap().into_raw()
2308}
2309
2310#[no_mangle]
2321pub unsafe extern "C" fn yxmltext_insert(
2322 txt: *const Branch,
2323 txn: *mut Transaction,
2324 index: u32,
2325 str: *const c_char,
2326 attrs: *const YInput,
2327) {
2328 assert!(!txt.is_null());
2329 assert!(!txn.is_null());
2330 assert!(!str.is_null());
2331
2332 let txt = XmlTextRef::from_raw_branch(txt);
2333 let txn = txn.as_mut().unwrap();
2334 let txn = txn
2335 .as_mut()
2336 .expect("provided transaction was not writeable");
2337 let chunk = CStr::from_ptr(str).to_str().unwrap();
2338
2339 if attrs.is_null() {
2340 txt.insert(txn, index as u32, chunk)
2341 } else {
2342 if let Some(attrs) = map_attrs(attrs.read().into()) {
2343 txt.insert_with_attributes(txn, index as u32, chunk, attrs)
2344 } else {
2345 panic!("yxmltext_insert: passed attributes are not of map type")
2346 }
2347 }
2348}
2349
2350#[no_mangle]
2361pub unsafe extern "C" fn yxmltext_insert_embed(
2362 txt: *const Branch,
2363 txn: *mut Transaction,
2364 index: u32,
2365 content: *const YInput,
2366 attrs: *const YInput,
2367) {
2368 assert!(!txt.is_null());
2369 assert!(!txn.is_null());
2370 assert!(!content.is_null());
2371
2372 let txn = txn.as_mut().unwrap();
2373 let txn = txn
2374 .as_mut()
2375 .expect("provided transaction was not writeable");
2376 let txt = XmlTextRef::from_raw_branch(txt);
2377 let index = index as u32;
2378 let content = content.read();
2379 if attrs.is_null() {
2380 txt.insert_embed(txn, index, content);
2381 } else {
2382 if let Some(attrs) = map_attrs(attrs.read().into()) {
2383 txt.insert_embed_with_attributes(txn, index, content, attrs);
2384 } else {
2385 panic!("yxmltext_insert_embed: passed attributes are not of map type")
2386 }
2387 }
2388}
2389
2390#[no_mangle]
2393pub unsafe extern "C" fn yxmltext_format(
2394 txt: *const Branch,
2395 txn: *mut Transaction,
2396 index: u32,
2397 len: u32,
2398 attrs: *const YInput,
2399) {
2400 assert!(!txt.is_null());
2401 assert!(!txn.is_null());
2402 assert!(!attrs.is_null());
2403
2404 if let Some(attrs) = map_attrs(attrs.read().into()) {
2405 let txt = XmlTextRef::from_raw_branch(txt);
2406 let txn = txn.as_mut().unwrap();
2407 let txn = txn
2408 .as_mut()
2409 .expect("provided transaction was not writeable");
2410 let index = index as u32;
2411 let len = len as u32;
2412 txt.format(txn, index, len, attrs);
2413 } else {
2414 panic!("yxmltext_format: passed attributes are not of map type")
2415 }
2416}
2417
2418#[no_mangle]
2427pub unsafe extern "C" fn yxmltext_remove_range(
2428 txt: *const Branch,
2429 txn: *mut Transaction,
2430 idx: u32,
2431 len: u32,
2432) {
2433 assert!(!txt.is_null());
2434 assert!(!txn.is_null());
2435
2436 let txt = XmlTextRef::from_raw_branch(txt);
2437 let txn = txn.as_mut().unwrap();
2438 let txn = txn
2439 .as_mut()
2440 .expect("provided transaction was not writeable");
2441 txt.remove_range(txn, idx as u32, len as u32)
2442}
2443
2444#[no_mangle]
2450pub unsafe extern "C" fn yxmltext_insert_attr(
2451 txt: *const Branch,
2452 txn: *mut Transaction,
2453 attr_name: *const c_char,
2454 attr_value: *const c_char,
2455) {
2456 assert!(!txt.is_null());
2457 assert!(!txn.is_null());
2458 assert!(!attr_name.is_null());
2459 assert!(!attr_value.is_null());
2460
2461 let txt = XmlTextRef::from_raw_branch(txt);
2462 let txn = txn.as_mut().unwrap();
2463 let txn = txn
2464 .as_mut()
2465 .expect("provided transaction was not writeable");
2466
2467 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2468 let value = CStr::from_ptr(attr_value).to_str().unwrap();
2469
2470 txt.insert_attribute(txn, name, value)
2471}
2472
2473#[no_mangle]
2477pub unsafe extern "C" fn yxmltext_remove_attr(
2478 txt: *const Branch,
2479 txn: *mut Transaction,
2480 attr_name: *const c_char,
2481) {
2482 assert!(!txt.is_null());
2483 assert!(!txn.is_null());
2484 assert!(!attr_name.is_null());
2485
2486 let txt = XmlTextRef::from_raw_branch(txt);
2487 let txn = txn.as_mut().unwrap();
2488 let txn = txn
2489 .as_mut()
2490 .expect("provided transaction was not writeable");
2491 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2492
2493 txt.remove_attribute(txn, &name)
2494}
2495
2496#[no_mangle]
2502pub unsafe extern "C" fn yxmltext_get_attr(
2503 txt: *const Branch,
2504 txn: *const Transaction,
2505 attr_name: *const c_char,
2506) -> *mut c_char {
2507 assert!(!txt.is_null());
2508 assert!(!attr_name.is_null());
2509 assert!(!txn.is_null());
2510
2511 let txn = txn.as_ref().unwrap();
2512 let txt = XmlTextRef::from_raw_branch(txt);
2513 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2514
2515 if let Some(value) = txt.get_attribute(txn, name) {
2516 CString::new(value).unwrap().into_raw()
2517 } else {
2518 std::ptr::null_mut()
2519 }
2520}
2521
2522#[no_mangle]
2528pub unsafe extern "C" fn ytext_chunks(
2529 txt: *const Branch,
2530 txn: *const Transaction,
2531 chunks_len: *mut u32,
2532) -> *mut YChunk {
2533 assert!(!txt.is_null());
2534 assert!(!txn.is_null());
2535
2536 let txt = TextRef::from_raw_branch(txt);
2537 let txn = txn.as_ref().unwrap();
2538
2539 let diffs = txt.diff(txn, YChange::identity);
2540 let chunks: Vec<_> = diffs.into_iter().map(YChunk::from).collect();
2541 let out = chunks.into_boxed_slice();
2542 *chunks_len = out.len() as u32;
2543 Box::into_raw(out) as *mut _
2544}
2545
2546#[no_mangle]
2548pub unsafe extern "C" fn ychunks_destroy(chunks: *mut YChunk, len: u32) {
2549 drop(Vec::from_raw_parts(chunks, len as usize, len as usize));
2550}
2551
2552pub const YCHANGE_ADD: i8 = 1;
2553pub const YCHANGE_RETAIN: i8 = 0;
2554pub const YCHANGE_REMOVE: i8 = -1;
2555
2556#[repr(C)]
2558pub struct YChunk {
2559 pub data: YOutput,
2562 pub fmt_len: u32,
2564 pub fmt: *mut YMapEntry,
2566}
2567
2568impl From<Diff<YChange>> for YChunk {
2569 fn from(diff: Diff<YChange>) -> Self {
2570 let data = YOutput::from(diff.insert);
2571 let mut fmt_len = 0;
2572 let fmt = if let Some(attrs) = diff.attributes {
2573 fmt_len = attrs.len() as u32;
2574 let mut fmt = Vec::with_capacity(attrs.len());
2575 for (k, v) in attrs.into_iter() {
2576 let output = YOutput::from(&v); let e = YMapEntry::new(k.as_ref(), Box::new(output));
2578 fmt.push(e);
2579 }
2580 Box::into_raw(fmt.into_boxed_slice()) as *mut _
2581 } else {
2582 null_mut()
2583 };
2584 YChunk { data, fmt_len, fmt }
2585 }
2586}
2587
2588impl Drop for YChunk {
2589 fn drop(&mut self) {
2590 if !self.fmt.is_null() {
2591 drop(unsafe {
2592 Vec::from_raw_parts(self.fmt, self.fmt_len as usize, self.fmt_len as usize)
2593 });
2594 }
2595 }
2596}
2597
2598#[repr(C)]
2605pub struct YInput {
2606 pub tag: i8,
2623
2624 pub len: u32,
2633
2634 value: YInputContent,
2636}
2637
2638impl YInput {
2639 fn into(self) -> Any {
2640 let tag = self.tag;
2641 unsafe {
2642 match tag {
2643 Y_JSON_STR => {
2644 let str = CStr::from_ptr(self.value.str).to_str().unwrap().into();
2645 Any::String(str)
2646 }
2647 Y_JSON => {
2648 let json_str = CStr::from_ptr(self.value.str).to_str().unwrap();
2649 serde_json::from_str(json_str).unwrap()
2650 }
2651 Y_JSON_NULL => Any::Null,
2652 Y_JSON_UNDEF => Any::Undefined,
2653 Y_JSON_INT => Any::BigInt(self.value.integer),
2654 Y_JSON_NUM => Any::Number(self.value.num),
2655 Y_JSON_BOOL => Any::Bool(if self.value.flag == 0 { false } else { true }),
2656 Y_JSON_BUF => Any::from(std::slice::from_raw_parts(
2657 self.value.buf as *mut u8,
2658 self.len as usize,
2659 )),
2660 Y_JSON_ARR => {
2661 let ptr = self.value.values;
2662 let mut dst: Vec<Any> = Vec::with_capacity(self.len as usize);
2663 let mut i = 0;
2664 while i < self.len as isize {
2665 let value = ptr.offset(i).read();
2666 let any = value.into();
2667 dst.push(any);
2668 i += 1;
2669 }
2670 Any::from(dst)
2671 }
2672 Y_JSON_MAP => {
2673 let mut dst = HashMap::with_capacity(self.len as usize);
2674 let keys = self.value.map.keys;
2675 let values = self.value.map.values;
2676 let mut i = 0;
2677 while i < self.len as isize {
2678 let key = CStr::from_ptr(keys.offset(i).read())
2679 .to_str()
2680 .unwrap()
2681 .to_owned();
2682 let value = values.offset(i).read().into();
2683 dst.insert(key, value);
2684 i += 1;
2685 }
2686 Any::from(dst)
2687 }
2688 Y_DOC => Any::Undefined,
2689 other => panic!("Cannot convert input - unknown tag: {}", other),
2690 }
2691 }
2692 }
2693}
2694
2695impl Into<EmbedPrelim<YInput>> for YInput {
2696 fn into(self) -> EmbedPrelim<YInput> {
2697 if self.tag <= 0 {
2698 EmbedPrelim::Primitive(self.into())
2699 } else {
2700 EmbedPrelim::Shared(self)
2701 }
2702 }
2703}
2704
2705#[repr(C)]
2706union YInputContent {
2707 flag: u8,
2708 num: f64,
2709 integer: i64,
2710 str: *mut c_char,
2711 buf: *mut c_char,
2712 values: *mut YInput,
2713 map: ManuallyDrop<YMapInputData>,
2714 doc: *mut Doc,
2715 weak: *const Weak,
2716}
2717
2718#[repr(C)]
2719struct YMapInputData {
2720 keys: *mut *mut c_char,
2721 values: *mut YInput,
2722}
2723
2724impl Drop for YInput {
2725 fn drop(&mut self) {}
2726}
2727
2728impl Prelim for YInput {
2729 type Return = Unused;
2730
2731 fn into_content<'doc>(self, _: &mut yrs::TransactionMut<'doc>) -> (ItemContent, Option<Self>) {
2732 unsafe {
2733 if self.tag <= 0 {
2734 (ItemContent::Any(vec![self.into()]), None)
2735 } else if self.tag == Y_DOC {
2736 let doc = self.value.doc.as_ref().unwrap();
2737 (ItemContent::Doc(None, doc.clone()), None)
2738 } else {
2739 let type_ref = match self.tag {
2740 Y_MAP => TypeRef::Map,
2741 Y_ARRAY => TypeRef::Array,
2742 Y_TEXT => TypeRef::Text,
2743 Y_XML_TEXT => TypeRef::XmlText,
2744 Y_XML_ELEM => {
2745 let name: Arc<str> =
2746 CStr::from_ptr(self.value.str).to_str().unwrap().into();
2747 TypeRef::XmlElement(name)
2748 }
2749 Y_WEAK_LINK => {
2750 let source = Arc::from_raw(self.value.weak);
2751 TypeRef::WeakLink(source)
2752 }
2753 Y_XML_FRAG => TypeRef::XmlFragment,
2754 other => panic!("unrecognized YInput tag: {}", other),
2755 };
2756 let inner = Branch::new(type_ref);
2757 (ItemContent::Type(inner), Some(self))
2758 }
2759 }
2760 }
2761
2762 fn integrate(self, txn: &mut yrs::TransactionMut, inner_ref: BranchPtr) {
2763 unsafe {
2764 match self.tag {
2765 Y_MAP => {
2766 let map = MapRef::from(inner_ref);
2767 let keys = self.value.map.keys;
2768 let values = self.value.map.values;
2769 let mut i = 0;
2770 while i < self.len as isize {
2771 let key = CStr::from_ptr(keys.offset(i).read())
2772 .to_str()
2773 .unwrap()
2774 .to_owned();
2775 let value = values.offset(i).read();
2776 map.insert(txn, key, value);
2777 i += 1;
2778 }
2779 }
2780 Y_ARRAY => {
2781 let array = ArrayRef::from(inner_ref);
2782 let ptr = self.value.values;
2783 let len = self.len as isize;
2784 let mut i = 0;
2785 while i < len {
2786 let value = ptr.offset(i).read();
2787 array.push_back(txn, value);
2788 i += 1;
2789 }
2790 }
2791 Y_TEXT => {
2792 let text = TextRef::from(inner_ref);
2793 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2794 text.push(txn, init);
2795 }
2796 Y_XML_TEXT => {
2797 let text = XmlTextRef::from(inner_ref);
2798 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2799 text.push(txn, init);
2800 }
2801 _ => { }
2802 }
2803 }
2804 }
2805}
2806
2807#[repr(C)]
2813pub struct YOutput {
2814 pub tag: i8,
2832
2833 pub len: u32,
2841
2842 value: YOutputContent,
2844}
2845
2846impl YOutput {
2847 #[inline]
2848 unsafe fn null() -> YOutput {
2849 YOutput {
2850 tag: Y_JSON_NULL,
2851 len: 0,
2852 value: MaybeUninit::uninit().assume_init(),
2853 }
2854 }
2855
2856 #[inline]
2857 unsafe fn undefined() -> YOutput {
2858 YOutput {
2859 tag: Y_JSON_UNDEF,
2860 len: 0,
2861 value: MaybeUninit::uninit().assume_init(),
2862 }
2863 }
2864}
2865
2866impl std::fmt::Display for YOutput {
2867 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2868 let tag = self.tag;
2869 unsafe {
2870 if tag == Y_JSON_INT {
2871 write!(f, "{}", self.value.integer)
2872 } else if tag == Y_JSON_NUM {
2873 write!(f, "{}", self.value.num)
2874 } else if tag == Y_JSON_BOOL {
2875 write!(
2876 f,
2877 "{}",
2878 if self.value.flag == 0 {
2879 "false"
2880 } else {
2881 "true"
2882 }
2883 )
2884 } else if tag == Y_JSON_UNDEF {
2885 write!(f, "undefined")
2886 } else if tag == Y_JSON_NULL {
2887 write!(f, "null")
2888 } else if tag == Y_JSON_STR {
2889 write!(f, "{}", CString::from_raw(self.value.str).to_str().unwrap())
2890 } else if tag == Y_MAP {
2891 write!(f, "YMap")
2892 } else if tag == Y_ARRAY {
2893 write!(f, "YArray")
2894 } else if tag == Y_JSON_ARR {
2895 write!(f, "[")?;
2896 let slice = std::slice::from_raw_parts(self.value.array, self.len as usize);
2897 for o in slice {
2898 write!(f, ", {}", o)?;
2899 }
2900 write!(f, "]")
2901 } else if tag == Y_JSON_MAP {
2902 write!(f, "{{")?;
2903 let slice = std::slice::from_raw_parts(self.value.map, self.len as usize);
2904 for e in slice {
2905 let key = CStr::from_ptr(e.key).to_str().unwrap();
2906 let value = e.value.as_ref().unwrap();
2907 write!(f, ", '{}' => {}", key, value)?;
2908 }
2909 write!(f, "}}")
2910 } else if tag == Y_TEXT {
2911 write!(f, "YText")
2912 } else if tag == Y_XML_TEXT {
2913 write!(f, "YXmlText")
2914 } else if tag == Y_XML_ELEM {
2915 write!(f, "YXmlElement",)
2916 } else if tag == Y_JSON_BUF {
2917 write!(f, "YBinary(len: {})", self.len)
2918 } else {
2919 Ok(())
2920 }
2921 }
2922 }
2923}
2924
2925impl Drop for YOutput {
2926 fn drop(&mut self) {
2927 let tag = self.tag;
2928 unsafe {
2929 match tag {
2930 Y_JSON_STR => drop(CString::from_raw(self.value.str)),
2931 Y_JSON_ARR => drop(Vec::from_raw_parts(
2932 self.value.array,
2933 self.len as usize,
2934 self.len as usize,
2935 )),
2936 Y_JSON_MAP => drop(Vec::from_raw_parts(
2937 self.value.map,
2938 self.len as usize,
2939 self.len as usize,
2940 )),
2941 Y_JSON_BUF => drop(Vec::from_raw_parts(
2942 self.value.buf as *mut u8,
2944 self.len as usize,
2945 self.len as usize,
2946 )),
2947 Y_DOC => drop(Box::from_raw(self.value.y_doc)),
2948 _ => { }
2949 }
2950 }
2951 }
2952}
2953
2954impl From<Out> for YOutput {
2955 fn from(v: Out) -> Self {
2956 match v {
2957 Out::Any(v) => Self::from(v),
2958 Out::YText(v) => Self::from(v),
2959 Out::YArray(v) => Self::from(v),
2960 Out::YMap(v) => Self::from(v),
2961 Out::YXmlElement(v) => Self::from(v),
2962 Out::YXmlFragment(v) => Self::from(v),
2963 Out::YXmlText(v) => Self::from(v),
2964 Out::YDoc(v) => Self::from(v),
2965 Out::YWeakLink(v) => Self::from(v),
2966 Out::UndefinedRef(v) => Self::from(v),
2967 }
2968 }
2969}
2970
2971impl From<bool> for YOutput {
2972 #[inline]
2973 fn from(value: bool) -> Self {
2974 YOutput {
2975 tag: Y_JSON_BOOL,
2976 len: 1,
2977 value: YOutputContent {
2978 flag: if value { Y_TRUE } else { Y_FALSE },
2979 },
2980 }
2981 }
2982}
2983
2984impl From<f64> for YOutput {
2985 #[inline]
2986 fn from(value: f64) -> Self {
2987 YOutput {
2988 tag: Y_JSON_NUM,
2989 len: 1,
2990 value: YOutputContent { num: value },
2991 }
2992 }
2993}
2994
2995impl From<i64> for YOutput {
2996 #[inline]
2997 fn from(value: i64) -> Self {
2998 YOutput {
2999 tag: Y_JSON_INT,
3000 len: 1,
3001 value: YOutputContent { integer: value },
3002 }
3003 }
3004}
3005
3006impl<'a> From<&'a str> for YOutput {
3007 fn from(value: &'a str) -> Self {
3008 YOutput {
3009 tag: Y_JSON_STR,
3010 len: value.len() as u32,
3011 value: YOutputContent {
3012 str: CString::new(value).unwrap().into_raw(),
3013 },
3014 }
3015 }
3016}
3017
3018impl<'a> From<&'a [u8]> for YOutput {
3019 fn from(value: &'a [u8]) -> Self {
3020 let value: Box<[u8]> = value.into();
3021 YOutput {
3022 tag: Y_JSON_BUF,
3023 len: value.len() as u32,
3024 value: YOutputContent {
3025 buf: Box::into_raw(value) as *const u8 as *mut c_char,
3026 },
3027 }
3028 }
3029}
3030
3031impl<'a> From<&'a [Any]> for YOutput {
3032 fn from(values: &'a [Any]) -> Self {
3033 let len = values.len() as u32;
3034 let mut array = Vec::with_capacity(values.len());
3035 for v in values.iter() {
3036 let output = YOutput::from(v);
3037 array.push(output);
3038 }
3039 let ptr = array.as_mut_ptr();
3040 forget(array);
3041 YOutput {
3042 tag: Y_JSON_ARR,
3043 len,
3044 value: YOutputContent { array: ptr },
3045 }
3046 }
3047}
3048
3049impl<'a> From<&'a HashMap<String, Any>> for YOutput {
3050 fn from(value: &'a HashMap<String, Any>) -> Self {
3051 let len = value.len() as u32;
3052 let mut array = Vec::with_capacity(len as usize);
3053 for (k, v) in value.iter() {
3054 let entry = YMapEntry::new(k.as_str(), Box::new(YOutput::from(v)));
3055 array.push(entry);
3056 }
3057 let ptr = array.as_mut_ptr();
3058 forget(array);
3059 YOutput {
3060 tag: Y_JSON_MAP,
3061 len,
3062 value: YOutputContent { map: ptr },
3063 }
3064 }
3065}
3066
3067impl<'a> From<&'a Any> for YOutput {
3068 fn from(v: &'a Any) -> Self {
3069 unsafe {
3070 match v {
3071 Any::Null => YOutput::null(),
3072 Any::Undefined => YOutput::undefined(),
3073 Any::Bool(v) => YOutput::from(*v),
3074 Any::Number(v) => YOutput::from(*v),
3075 Any::BigInt(v) => YOutput::from(*v),
3076 Any::String(v) => YOutput::from(v.as_ref()),
3077 Any::Buffer(v) => YOutput::from(v.as_ref()),
3078 Any::Array(v) => YOutput::from(v.as_ref()),
3079 Any::Map(v) => YOutput::from(v.as_ref()),
3080 }
3081 }
3082 }
3083}
3084
3085impl From<Any> for YOutput {
3086 fn from(v: Any) -> Self {
3087 unsafe {
3088 match v {
3089 Any::Null => YOutput::null(),
3090 Any::Undefined => YOutput::undefined(),
3091 Any::Bool(v) => YOutput::from(v),
3092 Any::Number(v) => YOutput::from(v),
3093 Any::BigInt(v) => YOutput::from(v),
3094 Any::String(v) => YOutput::from(v.as_ref()),
3095 Any::Buffer(v) => YOutput::from(v.as_ref()),
3096 Any::Array(v) => YOutput::from(v.as_ref()),
3097 Any::Map(v) => YOutput::from(v.as_ref()),
3098 }
3099 }
3100 }
3101}
3102
3103impl From<TextRef> for YOutput {
3104 fn from(v: TextRef) -> Self {
3105 YOutput {
3106 tag: Y_TEXT,
3107 len: 1,
3108 value: YOutputContent {
3109 y_type: v.into_raw_branch(),
3110 },
3111 }
3112 }
3113}
3114
3115impl From<ArrayRef> for YOutput {
3116 fn from(v: ArrayRef) -> Self {
3117 YOutput {
3118 tag: Y_ARRAY,
3119 len: 1,
3120 value: YOutputContent {
3121 y_type: v.into_raw_branch(),
3122 },
3123 }
3124 }
3125}
3126
3127impl From<WeakRef<BranchPtr>> for YOutput {
3128 fn from(v: WeakRef<BranchPtr>) -> Self {
3129 YOutput {
3130 tag: Y_WEAK_LINK,
3131 len: 1,
3132 value: YOutputContent {
3133 y_type: v.into_raw_branch(),
3134 },
3135 }
3136 }
3137}
3138
3139impl From<MapRef> for YOutput {
3140 fn from(v: MapRef) -> Self {
3141 YOutput {
3142 tag: Y_MAP,
3143 len: 1,
3144 value: YOutputContent {
3145 y_type: v.into_raw_branch(),
3146 },
3147 }
3148 }
3149}
3150
3151impl From<BranchPtr> for YOutput {
3152 fn from(v: BranchPtr) -> Self {
3153 let branch_ref = v.as_ref();
3154 YOutput {
3155 tag: Y_UNDEFINED,
3156 len: 1,
3157 value: YOutputContent {
3158 y_type: branch_ref as *const Branch as *mut Branch,
3159 },
3160 }
3161 }
3162}
3163
3164impl From<XmlElementRef> for YOutput {
3165 fn from(v: XmlElementRef) -> Self {
3166 YOutput {
3167 tag: Y_XML_ELEM,
3168 len: 1,
3169 value: YOutputContent {
3170 y_type: v.into_raw_branch(),
3171 },
3172 }
3173 }
3174}
3175
3176impl From<XmlTextRef> for YOutput {
3177 fn from(v: XmlTextRef) -> Self {
3178 YOutput {
3179 tag: Y_XML_TEXT,
3180 len: 1,
3181 value: YOutputContent {
3182 y_type: v.into_raw_branch(),
3183 },
3184 }
3185 }
3186}
3187
3188impl From<XmlFragmentRef> for YOutput {
3189 fn from(v: XmlFragmentRef) -> Self {
3190 YOutput {
3191 tag: Y_XML_FRAG,
3192 len: 1,
3193 value: YOutputContent {
3194 y_type: v.into_raw_branch(),
3195 },
3196 }
3197 }
3198}
3199
3200impl From<Doc> for YOutput {
3201 fn from(v: Doc) -> Self {
3202 YOutput {
3203 tag: Y_DOC,
3204 len: 1,
3205 value: YOutputContent {
3206 y_doc: Box::into_raw(Box::new(v.clone())),
3207 },
3208 }
3209 }
3210}
3211
3212#[repr(C)]
3213union YOutputContent {
3214 flag: u8,
3215 num: f64,
3216 integer: i64,
3217 str: *mut c_char,
3218 buf: *const c_char,
3219 array: *mut YOutput,
3220 map: *mut YMapEntry,
3221 y_type: *mut Branch,
3222 y_doc: *mut Doc,
3223}
3224
3225#[no_mangle]
3227pub unsafe extern "C" fn youtput_destroy(val: *mut YOutput) {
3228 if !val.is_null() {
3229 drop(Box::from_raw(val))
3230 }
3231}
3232
3233#[no_mangle]
3236pub unsafe extern "C" fn yinput_null() -> YInput {
3237 YInput {
3238 tag: Y_JSON_NULL,
3239 len: 0,
3240 value: MaybeUninit::uninit().assume_init(),
3241 }
3242}
3243
3244#[no_mangle]
3247pub unsafe extern "C" fn yinput_undefined() -> YInput {
3248 YInput {
3249 tag: Y_JSON_UNDEF,
3250 len: 0,
3251 value: MaybeUninit::uninit().assume_init(),
3252 }
3253}
3254
3255#[no_mangle]
3258pub unsafe extern "C" fn yinput_bool(flag: u8) -> YInput {
3259 YInput {
3260 tag: Y_JSON_BOOL,
3261 len: 1,
3262 value: YInputContent { flag },
3263 }
3264}
3265
3266#[no_mangle]
3269pub unsafe extern "C" fn yinput_float(num: f64) -> YInput {
3270 YInput {
3271 tag: Y_JSON_NUM,
3272 len: 1,
3273 value: YInputContent { num },
3274 }
3275}
3276
3277#[no_mangle]
3280pub unsafe extern "C" fn yinput_long(integer: i64) -> YInput {
3281 YInput {
3282 tag: Y_JSON_INT,
3283 len: 1,
3284 value: YInputContent { integer },
3285 }
3286}
3287
3288#[no_mangle]
3293pub unsafe extern "C" fn yinput_string(str: *const c_char) -> YInput {
3294 YInput {
3295 tag: Y_JSON_STR,
3296 len: 1,
3297 value: YInputContent {
3298 str: str as *mut c_char,
3299 },
3300 }
3301}
3302
3303#[no_mangle]
3309pub unsafe extern "C" fn yinput_json(str: *const c_char) -> YInput {
3310 YInput {
3311 tag: Y_JSON,
3312 len: 1,
3313 value: YInputContent {
3314 str: str as *mut c_char,
3315 },
3316 }
3317}
3318
3319#[no_mangle]
3323pub unsafe extern "C" fn yinput_binary(buf: *const c_char, len: u32) -> YInput {
3324 YInput {
3325 tag: Y_JSON_BUF,
3326 len,
3327 value: YInputContent {
3328 buf: buf as *mut c_char,
3329 },
3330 }
3331}
3332
3333#[no_mangle]
3337pub unsafe extern "C" fn yinput_json_array(values: *mut YInput, len: u32) -> YInput {
3338 YInput {
3339 tag: Y_JSON_ARR,
3340 len,
3341 value: YInputContent { values },
3342 }
3343}
3344
3345#[no_mangle]
3352pub unsafe extern "C" fn yinput_json_map(
3353 keys: *mut *mut c_char,
3354 values: *mut YInput,
3355 len: u32,
3356) -> YInput {
3357 YInput {
3358 tag: Y_JSON_MAP,
3359 len,
3360 value: YInputContent {
3361 map: ManuallyDrop::new(YMapInputData { keys, values }),
3362 },
3363 }
3364}
3365
3366#[no_mangle]
3371pub unsafe extern "C" fn yinput_yarray(values: *mut YInput, len: u32) -> YInput {
3372 YInput {
3373 tag: Y_ARRAY,
3374 len,
3375 value: YInputContent { values },
3376 }
3377}
3378
3379#[no_mangle]
3386pub unsafe extern "C" fn yinput_ymap(
3387 keys: *mut *mut c_char,
3388 values: *mut YInput,
3389 len: u32,
3390) -> YInput {
3391 YInput {
3392 tag: Y_MAP,
3393 len,
3394 value: YInputContent {
3395 map: ManuallyDrop::new(YMapInputData { keys, values }),
3396 },
3397 }
3398}
3399
3400#[no_mangle]
3406pub unsafe extern "C" fn yinput_ytext(str: *mut c_char) -> YInput {
3407 YInput {
3408 tag: Y_TEXT,
3409 len: 1,
3410 value: YInputContent { str },
3411 }
3412}
3413
3414#[no_mangle]
3420pub unsafe extern "C" fn yinput_yxmlelem(name: *mut c_char) -> YInput {
3421 YInput {
3422 tag: Y_XML_ELEM,
3423 len: 1,
3424 value: YInputContent { str: name },
3425 }
3426}
3427
3428#[no_mangle]
3434pub unsafe extern "C" fn yinput_yxmltext(str: *mut c_char) -> YInput {
3435 YInput {
3436 tag: Y_XML_TEXT,
3437 len: 1,
3438 value: YInputContent { str },
3439 }
3440}
3441
3442#[no_mangle]
3447pub unsafe extern "C" fn yinput_ydoc(doc: *mut Doc) -> YInput {
3448 YInput {
3449 tag: Y_DOC,
3450 len: 1,
3451 value: YInputContent { doc },
3452 }
3453}
3454
3455#[no_mangle]
3458pub unsafe extern "C" fn yinput_weak(weak: *const Weak) -> YInput {
3459 YInput {
3460 tag: Y_WEAK_LINK,
3461 len: 1,
3462 value: YInputContent { weak },
3463 }
3464}
3465
3466#[no_mangle]
3469pub unsafe extern "C" fn youtput_read_ydoc(val: *const YOutput) -> *mut Doc {
3470 let v = val.as_ref().unwrap();
3471 if v.tag == Y_DOC {
3472 v.value.y_doc
3473 } else {
3474 std::ptr::null_mut()
3475 }
3476}
3477
3478#[no_mangle]
3482pub unsafe extern "C" fn youtput_read_bool(val: *const YOutput) -> *const u8 {
3483 let v = val.as_ref().unwrap();
3484 if v.tag == Y_JSON_BOOL {
3485 &v.value.flag
3486 } else {
3487 std::ptr::null()
3488 }
3489}
3490
3491#[no_mangle]
3496pub unsafe extern "C" fn youtput_read_float(val: *const YOutput) -> *const f64 {
3497 let v = val.as_ref().unwrap();
3498 if v.tag == Y_JSON_NUM {
3499 &v.value.num
3500 } else {
3501 std::ptr::null()
3502 }
3503}
3504
3505#[no_mangle]
3510pub unsafe extern "C" fn youtput_read_long(val: *const YOutput) -> *const i64 {
3511 let v = val.as_ref().unwrap();
3512 if v.tag == Y_JSON_INT {
3513 &v.value.integer
3514 } else {
3515 std::ptr::null()
3516 }
3517}
3518
3519#[no_mangle]
3526pub unsafe extern "C" fn youtput_read_string(val: *const YOutput) -> *mut c_char {
3527 let v = val.as_ref().unwrap();
3528 if v.tag == Y_JSON_STR {
3529 v.value.str
3530 } else {
3531 std::ptr::null_mut()
3532 }
3533}
3534
3535#[no_mangle]
3542pub unsafe extern "C" fn youtput_read_binary(val: *const YOutput) -> *const c_char {
3543 let v = val.as_ref().unwrap();
3544 if v.tag == Y_JSON_BUF {
3545 v.value.buf
3546 } else {
3547 std::ptr::null()
3548 }
3549}
3550
3551#[no_mangle]
3558pub unsafe extern "C" fn youtput_read_json_array(val: *const YOutput) -> *mut YOutput {
3559 let v = val.as_ref().unwrap();
3560 if v.tag == Y_JSON_ARR {
3561 v.value.array
3562 } else {
3563 std::ptr::null_mut()
3564 }
3565}
3566
3567#[no_mangle]
3574pub unsafe extern "C" fn youtput_read_json_map(val: *const YOutput) -> *mut YMapEntry {
3575 let v = val.as_ref().unwrap();
3576 if v.tag == Y_JSON_MAP {
3577 v.value.map
3578 } else {
3579 std::ptr::null_mut()
3580 }
3581}
3582
3583#[no_mangle]
3589pub unsafe extern "C" fn youtput_read_yarray(val: *const YOutput) -> *mut Branch {
3590 let v = val.as_ref().unwrap();
3591 if v.tag == Y_ARRAY {
3592 v.value.y_type
3593 } else {
3594 std::ptr::null_mut()
3595 }
3596}
3597
3598#[no_mangle]
3604pub unsafe extern "C" fn youtput_read_yxmlelem(val: *const YOutput) -> *mut Branch {
3605 let v = val.as_ref().unwrap();
3606 if v.tag == Y_XML_ELEM {
3607 v.value.y_type
3608 } else {
3609 std::ptr::null_mut()
3610 }
3611}
3612
3613#[no_mangle]
3619pub unsafe extern "C" fn youtput_read_ymap(val: *const YOutput) -> *mut Branch {
3620 let v = val.as_ref().unwrap();
3621 if v.tag == Y_MAP {
3622 v.value.y_type
3623 } else {
3624 std::ptr::null_mut()
3625 }
3626}
3627
3628#[no_mangle]
3634pub unsafe extern "C" fn youtput_read_ytext(val: *const YOutput) -> *mut Branch {
3635 let v = val.as_ref().unwrap();
3636 if v.tag == Y_TEXT {
3637 v.value.y_type
3638 } else {
3639 std::ptr::null_mut()
3640 }
3641}
3642
3643#[no_mangle]
3649pub unsafe extern "C" fn youtput_read_yxmltext(val: *const YOutput) -> *mut Branch {
3650 let v = val.as_ref().unwrap();
3651 if v.tag == Y_XML_TEXT {
3652 v.value.y_type
3653 } else {
3654 std::ptr::null_mut()
3655 }
3656}
3657
3658#[no_mangle]
3664pub unsafe extern "C" fn youtput_read_yweak(val: *const YOutput) -> *mut Branch {
3665 let v = val.as_ref().unwrap();
3666 if v.tag == Y_WEAK_LINK {
3667 v.value.y_type
3668 } else {
3669 std::ptr::null_mut()
3670 }
3671}
3672
3673#[no_mangle]
3675pub unsafe extern "C" fn yunobserve(subscription: *mut Subscription) {
3676 drop(unsafe { Box::from_raw(subscription) })
3677}
3678
3679#[no_mangle]
3684pub unsafe extern "C" fn ytext_observe(
3685 txt: *const Branch,
3686 state: *mut c_void,
3687 cb: extern "C" fn(*mut c_void, *const YTextEvent),
3688) -> *mut Subscription {
3689 assert!(!txt.is_null());
3690 let state = CallbackState::new(state);
3691
3692 let txt = TextRef::from_raw_branch(txt);
3693 let subscription = txt.observe(move |txn, e| {
3694 let e = YTextEvent::new(e, txn);
3695 cb(state.0, &e as *const YTextEvent);
3696 });
3697 Box::into_raw(Box::new(subscription))
3698}
3699
3700#[no_mangle]
3705pub unsafe extern "C" fn ymap_observe(
3706 map: *const Branch,
3707 state: *mut c_void,
3708 cb: extern "C" fn(*mut c_void, *const YMapEvent),
3709) -> *mut Subscription {
3710 assert!(!map.is_null());
3711 let state = CallbackState::new(state);
3712
3713 let map = MapRef::from_raw_branch(map);
3714 let subscription = map.observe(move |txn, e| {
3715 let e = YMapEvent::new(e, txn);
3716 cb(state.0, &e as *const YMapEvent);
3717 });
3718 Box::into_raw(Box::new(subscription))
3719}
3720
3721#[no_mangle]
3726pub unsafe extern "C" fn yarray_observe(
3727 array: *const Branch,
3728 state: *mut c_void,
3729 cb: extern "C" fn(*mut c_void, *const YArrayEvent),
3730) -> *mut Subscription {
3731 assert!(!array.is_null());
3732 let state = CallbackState::new(state);
3733
3734 let array = ArrayRef::from_raw_branch(array);
3735 let subscription = array.observe(move |txn, e| {
3736 let e = YArrayEvent::new(e, txn);
3737 cb(state.0, &e as *const YArrayEvent);
3738 });
3739 Box::into_raw(Box::new(subscription))
3740}
3741
3742#[no_mangle]
3747pub unsafe extern "C" fn yxmlelem_observe(
3748 xml: *const Branch,
3749 state: *mut c_void,
3750 cb: extern "C" fn(*mut c_void, *const YXmlEvent),
3751) -> *mut Subscription {
3752 assert!(!xml.is_null());
3753 let state = CallbackState::new(state);
3754
3755 let xml = XmlElementRef::from_raw_branch(xml);
3756 let subscription = xml.observe(move |txn, e| {
3757 let e = YXmlEvent::new(e, txn);
3758 cb(state.0, &e as *const YXmlEvent);
3759 });
3760 Box::into_raw(Box::new(subscription))
3761}
3762
3763#[no_mangle]
3768pub unsafe extern "C" fn yxmltext_observe(
3769 xml: *const Branch,
3770 state: *mut c_void,
3771 cb: extern "C" fn(*mut c_void, *const YXmlTextEvent),
3772) -> *mut Subscription {
3773 assert!(!xml.is_null());
3774
3775 let state = CallbackState::new(state);
3776 let xml = XmlTextRef::from_raw_branch(xml);
3777 let subscription = xml.observe(move |txn, e| {
3778 let e = YXmlTextEvent::new(e, txn);
3779 cb(state.0, &e as *const YXmlTextEvent);
3780 });
3781 Box::into_raw(Box::new(subscription))
3782}
3783
3784#[no_mangle]
3791pub unsafe extern "C" fn yobserve_deep(
3792 ytype: *mut Branch,
3793 state: *mut c_void,
3794 cb: extern "C" fn(*mut c_void, u32, *const YEvent),
3795) -> *mut Subscription {
3796 assert!(!ytype.is_null());
3797
3798 let state = CallbackState::new(state);
3799 let branch = ytype.as_mut().unwrap();
3800 let subscription = branch.observe_deep(move |txn, events| {
3801 let events: Vec<_> = events.iter().map(|e| YEvent::new(txn, e)).collect();
3802 let len = events.len() as u32;
3803 cb(state.0, len, events.as_ptr());
3804 });
3805 Box::into_raw(Box::new(subscription))
3806}
3807
3808#[repr(C)]
3811pub struct YAfterTransactionEvent {
3812 pub before_state: YStateVector,
3814 pub after_state: YStateVector,
3816 pub delete_set: YDeleteSet,
3818}
3819
3820impl YAfterTransactionEvent {
3821 unsafe fn new(e: &TransactionCleanupEvent) -> Self {
3822 YAfterTransactionEvent {
3823 before_state: YStateVector::new(&e.before_state),
3824 after_state: YStateVector::new(&e.after_state),
3825 delete_set: YDeleteSet::new(&e.delete_set),
3826 }
3827 }
3828}
3829
3830#[repr(C)]
3831pub struct YSubdocsEvent {
3832 added_len: u32,
3833 removed_len: u32,
3834 loaded_len: u32,
3835 added: *mut *mut Doc,
3836 removed: *mut *mut Doc,
3837 loaded: *mut *mut Doc,
3838}
3839
3840impl YSubdocsEvent {
3841 unsafe fn new(e: &SubdocsEvent) -> Self {
3842 fn into_ptr(v: SubdocsEventIter) -> *mut *mut Doc {
3843 let array: Vec<_> = v.map(|doc| Box::into_raw(Box::new(doc.clone()))).collect();
3844 let mut boxed = array.into_boxed_slice();
3845 let ptr = boxed.as_mut_ptr();
3846 forget(boxed);
3847 ptr
3848 }
3849
3850 let added = e.added();
3851 let removed = e.removed();
3852 let loaded = e.loaded();
3853
3854 YSubdocsEvent {
3855 added_len: added.len() as u32,
3856 removed_len: removed.len() as u32,
3857 loaded_len: loaded.len() as u32,
3858 added: into_ptr(added),
3859 removed: into_ptr(removed),
3860 loaded: into_ptr(loaded),
3861 }
3862 }
3863}
3864
3865impl Drop for YSubdocsEvent {
3866 fn drop(&mut self) {
3867 fn release(len: u32, buf: *mut *mut Doc) {
3868 unsafe {
3869 let docs = Vec::from_raw_parts(buf, len as usize, len as usize);
3870 for d in docs {
3871 drop(Box::from_raw(d));
3872 }
3873 }
3874 }
3875
3876 release(self.added_len, self.added);
3877 release(self.removed_len, self.removed);
3878 release(self.loaded_len, self.loaded);
3879 }
3880}
3881
3882#[repr(C)]
3885pub struct YStateVector {
3886 pub entries_count: u32,
3888 pub client_ids: *mut u64,
3892 pub clocks: *mut u32,
3896}
3897
3898impl YStateVector {
3899 unsafe fn new(sv: &StateVector) -> Self {
3900 let entries_count = sv.len() as u32;
3901 let mut client_ids = Vec::with_capacity(sv.len());
3902 let mut clocks = Vec::with_capacity(sv.len());
3903 for (&client, &clock) in sv.iter() {
3904 client_ids.push(client as u64);
3905 clocks.push(clock as u32);
3906 }
3907
3908 YStateVector {
3909 entries_count,
3910 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
3911 clocks: Box::into_raw(clocks.into_boxed_slice()) as *mut _,
3912 }
3913 }
3914}
3915
3916impl Drop for YStateVector {
3917 fn drop(&mut self) {
3918 let len = self.entries_count as usize;
3919 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
3920 drop(unsafe { Vec::from_raw_parts(self.clocks, len, len) });
3921 }
3922}
3923
3924#[repr(C)]
3928pub struct YDeleteSet {
3929 pub entries_count: u32,
3931 pub client_ids: *mut u64,
3935 pub ranges: *mut YIdRangeSeq,
3939}
3940
3941impl YDeleteSet {
3942 unsafe fn new(ds: &DeleteSet) -> Self {
3943 let len = ds.len();
3944 let mut client_ids = Vec::with_capacity(len);
3945 let mut ranges = Vec::with_capacity(len);
3946
3947 for (&client, range) in ds.iter() {
3948 client_ids.push(client);
3949 let seq: Vec<_> = range
3950 .iter()
3951 .map(|r| YIdRange {
3952 start: r.start as u32,
3953 end: r.end as u32,
3954 })
3955 .collect();
3956 ranges.push(YIdRangeSeq {
3957 len: seq.len() as u32,
3958 seq: Box::into_raw(seq.into_boxed_slice()) as *mut _,
3959 })
3960 }
3961
3962 YDeleteSet {
3963 entries_count: len as u32,
3964 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
3965 ranges: Box::into_raw(ranges.into_boxed_slice()) as *mut _,
3966 }
3967 }
3968}
3969
3970impl Drop for YDeleteSet {
3971 fn drop(&mut self) {
3972 let len = self.entries_count as usize;
3973 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
3974 drop(unsafe { Vec::from_raw_parts(self.ranges, len, len) });
3975 }
3976}
3977
3978#[repr(C)]
3981pub struct YIdRangeSeq {
3982 pub len: u32,
3984 pub seq: *mut YIdRange,
3988}
3989
3990impl Drop for YIdRangeSeq {
3991 fn drop(&mut self) {
3992 let len = self.len as usize;
3993 drop(unsafe { Vec::from_raw_parts(self.seq, len, len) })
3994 }
3995}
3996
3997#[repr(C)]
3998pub struct YIdRange {
3999 pub start: u32,
4000 pub end: u32,
4001}
4002
4003#[repr(C)]
4004pub struct YEvent {
4005 pub tag: i8,
4013
4014 pub content: YEventContent,
4017}
4018
4019impl YEvent {
4020 fn new<'doc>(txn: &yrs::TransactionMut<'doc>, e: &Event) -> YEvent {
4021 match e {
4022 Event::Text(e) => YEvent {
4023 tag: Y_TEXT,
4024 content: YEventContent {
4025 text: YTextEvent::new(e, txn),
4026 },
4027 },
4028 Event::Array(e) => YEvent {
4029 tag: Y_ARRAY,
4030 content: YEventContent {
4031 array: YArrayEvent::new(e, txn),
4032 },
4033 },
4034 Event::Map(e) => YEvent {
4035 tag: Y_MAP,
4036 content: YEventContent {
4037 map: YMapEvent::new(e, txn),
4038 },
4039 },
4040 Event::XmlFragment(e) => YEvent {
4041 tag: if let XmlOut::Fragment(_) = e.target() {
4042 Y_XML_FRAG
4043 } else {
4044 Y_XML_ELEM
4045 },
4046 content: YEventContent {
4047 xml_elem: YXmlEvent::new(e, txn),
4048 },
4049 },
4050 Event::XmlText(e) => YEvent {
4051 tag: Y_XML_TEXT,
4052 content: YEventContent {
4053 xml_text: YXmlTextEvent::new(e, txn),
4054 },
4055 },
4056 Event::Weak(e) => YEvent {
4057 tag: Y_WEAK_LINK,
4058 content: YEventContent {
4059 weak: YWeakLinkEvent::new(e, txn),
4060 },
4061 },
4062 }
4063 }
4064}
4065
4066#[repr(C)]
4067pub union YEventContent {
4068 pub text: YTextEvent,
4069 pub map: YMapEvent,
4070 pub array: YArrayEvent,
4071 pub xml_elem: YXmlEvent,
4072 pub xml_text: YXmlTextEvent,
4073 pub weak: YWeakLinkEvent,
4074}
4075
4076#[repr(C)]
4080#[derive(Copy, Clone)]
4081pub struct YTextEvent {
4082 inner: *const c_void,
4083 txn: *const yrs::TransactionMut<'static>,
4084}
4085
4086impl YTextEvent {
4087 fn new<'dev>(inner: &TextEvent, txn: &yrs::TransactionMut<'dev>) -> Self {
4088 let inner = inner as *const TextEvent as *const _;
4089 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4090 let txn = txn as *const _;
4091 YTextEvent { inner, txn }
4092 }
4093
4094 fn txn(&self) -> &yrs::TransactionMut {
4095 unsafe { self.txn.as_ref().unwrap() }
4096 }
4097}
4098
4099impl Deref for YTextEvent {
4100 type Target = TextEvent;
4101
4102 fn deref(&self) -> &Self::Target {
4103 unsafe { (self.inner as *const TextEvent).as_ref().unwrap() }
4104 }
4105}
4106
4107#[repr(C)]
4111#[derive(Copy, Clone)]
4112pub struct YArrayEvent {
4113 inner: *const c_void,
4114 txn: *const yrs::TransactionMut<'static>,
4115}
4116
4117impl YArrayEvent {
4118 fn new<'doc>(inner: &ArrayEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4119 let inner = inner as *const ArrayEvent as *const _;
4120 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4121 let txn = txn as *const _;
4122 YArrayEvent { inner, txn }
4123 }
4124
4125 fn txn(&self) -> &yrs::TransactionMut {
4126 unsafe { self.txn.as_ref().unwrap() }
4127 }
4128}
4129
4130impl Deref for YArrayEvent {
4131 type Target = ArrayEvent;
4132
4133 fn deref(&self) -> &Self::Target {
4134 unsafe { (self.inner as *const ArrayEvent).as_ref().unwrap() }
4135 }
4136}
4137
4138#[repr(C)]
4142#[derive(Copy, Clone)]
4143pub struct YMapEvent {
4144 inner: *const c_void,
4145 txn: *const yrs::TransactionMut<'static>,
4146}
4147
4148impl YMapEvent {
4149 fn new<'doc>(inner: &MapEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4150 let inner = inner as *const MapEvent as *const _;
4151 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4152 let txn = txn as *const _;
4153 YMapEvent { inner, txn }
4154 }
4155
4156 fn txn(&self) -> &yrs::TransactionMut<'static> {
4157 unsafe { self.txn.as_ref().unwrap() }
4158 }
4159}
4160
4161impl Deref for YMapEvent {
4162 type Target = MapEvent;
4163
4164 fn deref(&self) -> &Self::Target {
4165 unsafe { (self.inner as *const MapEvent).as_ref().unwrap() }
4166 }
4167}
4168
4169#[repr(C)]
4174#[derive(Copy, Clone)]
4175pub struct YXmlEvent {
4176 inner: *const c_void,
4177 txn: *const yrs::TransactionMut<'static>,
4178}
4179
4180impl YXmlEvent {
4181 fn new<'doc>(inner: &XmlEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4182 let inner = inner as *const XmlEvent as *const _;
4183 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4184 let txn = txn as *const _;
4185 YXmlEvent { inner, txn }
4186 }
4187
4188 fn txn(&self) -> &yrs::TransactionMut<'static> {
4189 unsafe { self.txn.as_ref().unwrap() }
4190 }
4191}
4192
4193impl Deref for YXmlEvent {
4194 type Target = XmlEvent;
4195
4196 fn deref(&self) -> &Self::Target {
4197 unsafe { (self.inner as *const XmlEvent).as_ref().unwrap() }
4198 }
4199}
4200
4201#[repr(C)]
4206#[derive(Copy, Clone)]
4207pub struct YXmlTextEvent {
4208 inner: *const c_void,
4209 txn: *const yrs::TransactionMut<'static>,
4210}
4211
4212impl YXmlTextEvent {
4213 fn new<'doc>(inner: &XmlTextEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4214 let inner = inner as *const XmlTextEvent as *const _;
4215 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4216 let txn = txn as *const _;
4217 YXmlTextEvent { inner, txn }
4218 }
4219
4220 fn txn(&self) -> &yrs::TransactionMut<'static> {
4221 unsafe { self.txn.as_ref().unwrap() }
4222 }
4223}
4224
4225impl Deref for YXmlTextEvent {
4226 type Target = XmlTextEvent;
4227
4228 fn deref(&self) -> &Self::Target {
4229 unsafe { (self.inner as *const XmlTextEvent).as_ref().unwrap() }
4230 }
4231}
4232
4233#[repr(C)]
4236#[derive(Copy, Clone)]
4237pub struct YWeakLinkEvent {
4238 inner: *const c_void,
4239 txn: *const yrs::TransactionMut<'static>,
4240}
4241
4242impl YWeakLinkEvent {
4243 fn new<'doc>(inner: &WeakEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4244 let inner = inner as *const WeakEvent as *const _;
4245 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4246 let txn = txn as *const _;
4247 YWeakLinkEvent { inner, txn }
4248 }
4249}
4250
4251impl Deref for YWeakLinkEvent {
4252 type Target = WeakEvent;
4253
4254 fn deref(&self) -> &Self::Target {
4255 unsafe { (self.inner as *const WeakEvent).as_ref().unwrap() }
4256 }
4257}
4258
4259#[no_mangle]
4261pub unsafe extern "C" fn ytext_event_target(e: *const YTextEvent) -> *mut Branch {
4262 assert!(!e.is_null());
4263 let out = (&*e).target().clone();
4264 out.into_raw_branch()
4265}
4266
4267#[no_mangle]
4269pub unsafe extern "C" fn yarray_event_target(e: *const YArrayEvent) -> *mut Branch {
4270 assert!(!e.is_null());
4271 let out = (&*e).target().clone();
4272 out.into_raw_branch()
4273}
4274
4275#[no_mangle]
4277pub unsafe extern "C" fn ymap_event_target(e: *const YMapEvent) -> *mut Branch {
4278 assert!(!e.is_null());
4279 let out = (&*e).target().clone();
4280 out.into_raw_branch()
4281}
4282
4283#[no_mangle]
4285pub unsafe extern "C" fn yxmlelem_event_target(e: *const YXmlEvent) -> *mut Branch {
4286 assert!(!e.is_null());
4287 let out = (&*e).target().clone();
4288 match out {
4289 XmlOut::Element(e) => e.into_raw_branch(),
4290 XmlOut::Fragment(e) => e.into_raw_branch(),
4291 XmlOut::Text(e) => e.into_raw_branch(),
4292 }
4293}
4294
4295#[no_mangle]
4297pub unsafe extern "C" fn yxmltext_event_target(e: *const YXmlTextEvent) -> *mut Branch {
4298 assert!(!e.is_null());
4299 let out = (&*e).target().clone();
4300 out.into_raw_branch()
4301}
4302
4303#[no_mangle]
4310pub unsafe extern "C" fn ytext_event_path(
4311 e: *const YTextEvent,
4312 len: *mut u32,
4313) -> *mut YPathSegment {
4314 assert!(!e.is_null());
4315 let e = &*e;
4316 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4317 let out = path.into_boxed_slice();
4318 *len = out.len() as u32;
4319 Box::into_raw(out) as *mut _
4320}
4321
4322#[no_mangle]
4329pub unsafe extern "C" fn ymap_event_path(e: *const YMapEvent, len: *mut u32) -> *mut YPathSegment {
4330 assert!(!e.is_null());
4331 let e = &*e;
4332 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4333 let out = path.into_boxed_slice();
4334 *len = out.len() as u32;
4335 Box::into_raw(out) as *mut _
4336}
4337
4338#[no_mangle]
4345pub unsafe extern "C" fn yxmlelem_event_path(
4346 e: *const YXmlEvent,
4347 len: *mut u32,
4348) -> *mut YPathSegment {
4349 assert!(!e.is_null());
4350 let e = &*e;
4351 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4352 let out = path.into_boxed_slice();
4353 *len = out.len() as u32;
4354 Box::into_raw(out) as *mut _
4355}
4356
4357#[no_mangle]
4364pub unsafe extern "C" fn yxmltext_event_path(
4365 e: *const YXmlTextEvent,
4366 len: *mut u32,
4367) -> *mut YPathSegment {
4368 assert!(!e.is_null());
4369 let e = &*e;
4370 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4371 let out = path.into_boxed_slice();
4372 *len = out.len() as u32;
4373 Box::into_raw(out) as *mut _
4374}
4375
4376#[no_mangle]
4383pub unsafe extern "C" fn yarray_event_path(
4384 e: *const YArrayEvent,
4385 len: *mut u32,
4386) -> *mut YPathSegment {
4387 assert!(!e.is_null());
4388 let e = &*e;
4389 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4390 let out = path.into_boxed_slice();
4391 *len = out.len() as u32;
4392 Box::into_raw(out) as *mut _
4393}
4394
4395#[no_mangle]
4398pub unsafe extern "C" fn ypath_destroy(path: *mut YPathSegment, len: u32) {
4399 if !path.is_null() {
4400 drop(Vec::from_raw_parts(path, len as usize, len as usize));
4401 }
4402}
4403
4404#[no_mangle]
4411pub unsafe extern "C" fn ytext_event_delta(e: *const YTextEvent, len: *mut u32) -> *mut YDeltaOut {
4412 assert!(!e.is_null());
4413 let e = &*e;
4414 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4415
4416 let out = delta.into_boxed_slice();
4417 *len = out.len() as u32;
4418 Box::into_raw(out) as *mut _
4419}
4420
4421#[no_mangle]
4428pub unsafe extern "C" fn yxmltext_event_delta(
4429 e: *const YXmlTextEvent,
4430 len: *mut u32,
4431) -> *mut YDeltaOut {
4432 assert!(!e.is_null());
4433 let e = &*e;
4434 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4435
4436 let out = delta.into_boxed_slice();
4437 *len = out.len() as u32;
4438 Box::into_raw(out) as *mut _
4439}
4440
4441#[no_mangle]
4448pub unsafe extern "C" fn yarray_event_delta(
4449 e: *const YArrayEvent,
4450 len: *mut u32,
4451) -> *mut YEventChange {
4452 assert!(!e.is_null());
4453 let e = &*e;
4454 let delta: Vec<_> = e
4455 .delta(e.txn())
4456 .into_iter()
4457 .map(YEventChange::from)
4458 .collect();
4459
4460 let out = delta.into_boxed_slice();
4461 *len = out.len() as u32;
4462 Box::into_raw(out) as *mut _
4463}
4464
4465#[no_mangle]
4472pub unsafe extern "C" fn yxmlelem_event_delta(
4473 e: *const YXmlEvent,
4474 len: *mut u32,
4475) -> *mut YEventChange {
4476 assert!(!e.is_null());
4477 let e = &*e;
4478 let delta: Vec<_> = e
4479 .delta(e.txn())
4480 .into_iter()
4481 .map(YEventChange::from)
4482 .collect();
4483
4484 let out = delta.into_boxed_slice();
4485 *len = out.len() as u32;
4486 Box::into_raw(out) as *mut _
4487}
4488
4489#[no_mangle]
4491pub unsafe extern "C" fn ytext_delta_destroy(delta: *mut YDeltaOut, len: u32) {
4492 if !delta.is_null() {
4493 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4494 drop(delta);
4495 }
4496}
4497
4498#[no_mangle]
4500pub unsafe extern "C" fn yevent_delta_destroy(delta: *mut YEventChange, len: u32) {
4501 if !delta.is_null() {
4502 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4503 drop(delta);
4504 }
4505}
4506
4507#[no_mangle]
4514pub unsafe extern "C" fn ymap_event_keys(
4515 e: *const YMapEvent,
4516 len: *mut u32,
4517) -> *mut YEventKeyChange {
4518 assert!(!e.is_null());
4519 let e = &*e;
4520 let delta: Vec<_> = e
4521 .keys(e.txn())
4522 .into_iter()
4523 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4524 .collect();
4525
4526 let out = delta.into_boxed_slice();
4527 *len = out.len() as u32;
4528 Box::into_raw(out) as *mut _
4529}
4530
4531#[no_mangle]
4537pub unsafe extern "C" fn yxmlelem_event_keys(
4538 e: *const YXmlEvent,
4539 len: *mut u32,
4540) -> *mut YEventKeyChange {
4541 assert!(!e.is_null());
4542 let e = &*e;
4543 let delta: Vec<_> = e
4544 .keys(e.txn())
4545 .into_iter()
4546 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4547 .collect();
4548
4549 let out = delta.into_boxed_slice();
4550 *len = out.len() as u32;
4551 Box::into_raw(out) as *mut _
4552}
4553
4554#[no_mangle]
4560pub unsafe extern "C" fn yxmltext_event_keys(
4561 e: *const YXmlTextEvent,
4562 len: *mut u32,
4563) -> *mut YEventKeyChange {
4564 assert!(!e.is_null());
4565 let e = &*e;
4566 let delta: Vec<_> = e
4567 .keys(e.txn())
4568 .into_iter()
4569 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4570 .collect();
4571
4572 let out = delta.into_boxed_slice();
4573 *len = out.len() as u32;
4574 Box::into_raw(out) as *mut _
4575}
4576
4577#[no_mangle]
4580pub unsafe extern "C" fn yevent_keys_destroy(keys: *mut YEventKeyChange, len: u32) {
4581 if !keys.is_null() {
4582 drop(Vec::from_raw_parts(keys, len as usize, len as usize));
4583 }
4584}
4585
4586pub type YUndoManager = yrs::undo::UndoManager<AtomicPtr<c_void>>;
4587
4588#[repr(C)]
4589pub struct YUndoManagerOptions {
4590 pub capture_timeout_millis: i32,
4591}
4592
4593#[no_mangle]
4601pub unsafe extern "C" fn yundo_manager(
4602 doc: *const Doc,
4603 options: *const YUndoManagerOptions,
4604) -> *mut YUndoManager {
4605 let doc = doc.as_ref().unwrap();
4606
4607 let mut o = yrs::undo::Options::default();
4608 if let Some(options) = options.as_ref() {
4609 if options.capture_timeout_millis >= 0 {
4610 o.capture_timeout_millis = options.capture_timeout_millis as u64;
4611 }
4612 };
4613 let boxed = Box::new(yrs::undo::UndoManager::with_options(doc, o));
4614 Box::into_raw(boxed)
4615}
4616
4617#[no_mangle]
4619pub unsafe extern "C" fn yundo_manager_destroy(mgr: *mut YUndoManager) {
4620 drop(Box::from_raw(mgr));
4621}
4622
4623#[no_mangle]
4628pub unsafe extern "C" fn yundo_manager_add_origin(
4629 mgr: *mut YUndoManager,
4630 origin_len: u32,
4631 origin: *const c_char,
4632) {
4633 let mgr = mgr.as_mut().unwrap();
4634 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4635 mgr.include_origin(Origin::from(bytes));
4636}
4637
4638#[no_mangle]
4640pub unsafe extern "C" fn yundo_manager_remove_origin(
4641 mgr: *mut YUndoManager,
4642 origin_len: u32,
4643 origin: *const c_char,
4644) {
4645 let mgr = mgr.as_mut().unwrap();
4646 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4647 mgr.exclude_origin(Origin::from(bytes));
4648}
4649
4650#[no_mangle]
4652pub unsafe extern "C" fn yundo_manager_add_scope(mgr: *mut YUndoManager, ytype: *const Branch) {
4653 let mgr = mgr.as_mut().unwrap();
4654 let branch = ytype.as_ref().unwrap();
4655 mgr.expand_scope(&BranchPtr::from(branch));
4656}
4657
4658#[no_mangle]
4667pub unsafe extern "C" fn yundo_manager_clear(mgr: *mut YUndoManager) {
4668 let mgr = mgr.as_mut().unwrap();
4669 mgr.clear();
4670}
4671
4672#[no_mangle]
4679pub unsafe extern "C" fn yundo_manager_stop(mgr: *mut YUndoManager) {
4680 let mgr = mgr.as_mut().unwrap();
4681 mgr.reset();
4682}
4683
4684#[no_mangle]
4691pub unsafe extern "C" fn yundo_manager_undo(mgr: *mut YUndoManager) -> u8 {
4692 let mgr = mgr.as_mut().unwrap();
4693
4694 match mgr.try_undo() {
4695 Ok(true) => Y_TRUE,
4696 Ok(false) => Y_FALSE,
4697 Err(_) => Y_FALSE,
4698 }
4699}
4700
4701#[no_mangle]
4707pub unsafe extern "C" fn yundo_manager_redo(mgr: *mut YUndoManager) -> u8 {
4708 let mgr = mgr.as_mut().unwrap();
4709 match mgr.try_redo() {
4710 Ok(true) => Y_TRUE,
4711 Ok(false) => Y_FALSE,
4712 Err(_) => Y_FALSE,
4713 }
4714}
4715
4716#[no_mangle]
4718pub unsafe extern "C" fn yundo_manager_undo_stack_len(mgr: *mut YUndoManager) -> u32 {
4719 let mgr = mgr.as_mut().unwrap();
4720 mgr.undo_stack().len() as u32
4721}
4722
4723#[no_mangle]
4725pub unsafe extern "C" fn yundo_manager_redo_stack_len(mgr: *mut YUndoManager) -> u32 {
4726 let mgr = mgr.as_mut().unwrap();
4727 mgr.redo_stack().len() as u32
4728}
4729
4730#[no_mangle]
4736pub unsafe extern "C" fn yundo_manager_observe_added(
4737 mgr: *mut YUndoManager,
4738 state: *mut c_void,
4739 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4740) -> *mut Subscription {
4741 let state = CallbackState::new(state);
4742 let mgr = mgr.as_mut().unwrap();
4743 let subscription = mgr.observe_item_added(move |_, e| {
4744 let meta_ptr = {
4745 let event = YUndoEvent::new(e);
4746 callback(state.0, &event as *const YUndoEvent);
4747 event.meta
4748 };
4749 e.meta().store(meta_ptr, Ordering::Release);
4750 });
4751 Box::into_raw(Box::new(subscription))
4752}
4753
4754#[no_mangle]
4760pub unsafe extern "C" fn yundo_manager_observe_popped(
4761 mgr: *mut YUndoManager,
4762 state: *mut c_void,
4763 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4764) -> *mut Subscription {
4765 let mgr = mgr.as_mut().unwrap();
4766 let state = CallbackState::new(state);
4767 let subscription = mgr
4768 .observe_item_popped(move |_, e| {
4769 let meta_ptr = {
4770 let event = YUndoEvent::new(e);
4771 callback(state.0, &event as *const YUndoEvent);
4772 event.meta
4773 };
4774 e.meta().store(meta_ptr, Ordering::Release);
4775 })
4776 .into();
4777 Box::into_raw(Box::new(subscription))
4778}
4779
4780pub const Y_KIND_UNDO: c_char = 0;
4781pub const Y_KIND_REDO: c_char = 1;
4782
4783#[repr(C)]
4787pub struct YUndoEvent {
4788 pub kind: c_char,
4791 pub origin: *const c_char,
4794 pub origin_len: u32,
4798 pub meta: *mut c_void,
4808}
4809
4810impl YUndoEvent {
4811 unsafe fn new(e: &yrs::undo::Event<AtomicPtr<c_void>>) -> Self {
4812 let (origin, origin_len) = if let Some(origin) = e.origin() {
4813 let bytes = origin.as_ref();
4814 let origin_len = bytes.len() as u32;
4815 let origin = bytes.as_ptr() as *const c_char;
4816 (origin, origin_len)
4817 } else {
4818 (null(), 0)
4819 };
4820 YUndoEvent {
4821 kind: match e.kind() {
4822 EventKind::Undo => Y_KIND_UNDO,
4823 EventKind::Redo => Y_KIND_REDO,
4824 },
4825 origin,
4826 origin_len,
4827 meta: e.meta().load(Ordering::Acquire),
4828 }
4829 }
4830}
4831
4832#[no_mangle]
4836pub unsafe extern "C" fn ytype_kind(branch: *const Branch) -> i8 {
4837 if let Some(branch) = branch.as_ref() {
4838 match branch.type_ref() {
4839 TypeRef::Array => Y_ARRAY,
4840 TypeRef::Map => Y_MAP,
4841 TypeRef::Text => Y_TEXT,
4842 TypeRef::XmlElement(_) => Y_XML_ELEM,
4843 TypeRef::XmlText => Y_XML_TEXT,
4844 TypeRef::XmlFragment => Y_XML_FRAG,
4845 TypeRef::SubDoc => Y_DOC,
4846 TypeRef::WeakLink(_) => Y_WEAK_LINK,
4847 TypeRef::XmlHook => 0,
4848 TypeRef::Undefined => 0,
4849 }
4850 } else {
4851 0
4852 }
4853}
4854
4855pub const Y_EVENT_PATH_KEY: c_char = 1;
4857
4858pub const Y_EVENT_PATH_INDEX: c_char = 2;
4860
4861#[repr(C)]
4869pub struct YPathSegment {
4870 pub tag: c_char,
4878
4879 pub value: YPathSegmentCase,
4882}
4883
4884impl From<PathSegment> for YPathSegment {
4885 fn from(ps: PathSegment) -> Self {
4886 match ps {
4887 PathSegment::Key(key) => {
4888 let key = CString::new(key.as_ref()).unwrap().into_raw() as *const _;
4889 YPathSegment {
4890 tag: Y_EVENT_PATH_KEY,
4891 value: YPathSegmentCase { key },
4892 }
4893 }
4894 PathSegment::Index(index) => YPathSegment {
4895 tag: Y_EVENT_PATH_INDEX,
4896 value: YPathSegmentCase {
4897 index: index as u32,
4898 },
4899 },
4900 }
4901 }
4902}
4903
4904impl Drop for YPathSegment {
4905 fn drop(&mut self) {
4906 if self.tag == Y_EVENT_PATH_KEY {
4907 unsafe {
4908 ystring_destroy(self.value.key as *mut _);
4909 }
4910 }
4911 }
4912}
4913
4914#[repr(C)]
4915pub union YPathSegmentCase {
4916 pub key: *const c_char,
4917 pub index: u32,
4918}
4919
4920pub const Y_EVENT_CHANGE_ADD: u8 = 1;
4923
4924pub const Y_EVENT_CHANGE_DELETE: u8 = 2;
4927
4928pub const Y_EVENT_CHANGE_RETAIN: u8 = 3;
4931
4932#[repr(C)]
4948pub struct YEventChange {
4949 pub tag: u8,
4959
4960 pub len: u32,
4963
4964 pub values: *const YOutput,
4967}
4968
4969impl<'a> From<&'a Change> for YEventChange {
4970 fn from(change: &'a Change) -> Self {
4971 match change {
4972 Change::Added(values) => {
4973 let out: Vec<_> = values
4974 .into_iter()
4975 .map(|v| YOutput::from(v.clone()))
4976 .collect();
4977 let len = out.len() as u32;
4978 let out = out.into_boxed_slice();
4979 let values = Box::into_raw(out) as *mut _;
4980
4981 YEventChange {
4982 tag: Y_EVENT_CHANGE_ADD,
4983 len,
4984 values,
4985 }
4986 }
4987 Change::Removed(len) => YEventChange {
4988 tag: Y_EVENT_CHANGE_DELETE,
4989 len: *len as u32,
4990 values: null(),
4991 },
4992 Change::Retain(len) => YEventChange {
4993 tag: Y_EVENT_CHANGE_RETAIN,
4994 len: *len as u32,
4995 values: null(),
4996 },
4997 }
4998 }
4999}
5000
5001impl Drop for YEventChange {
5002 fn drop(&mut self) {
5003 if self.tag == Y_EVENT_CHANGE_ADD {
5004 unsafe {
5005 let len = self.len as usize;
5006 let values = Vec::from_raw_parts(self.values as *mut YOutput, len, len);
5007 drop(values);
5008 }
5009 }
5010 }
5011}
5012
5013#[repr(C)]
5032pub struct YDeltaOut {
5033 pub tag: u8,
5043
5044 pub len: u32,
5047
5048 pub attributes_len: u32,
5050
5051 pub attributes: *mut YDeltaAttr,
5054
5055 pub insert: *mut YOutput,
5058}
5059
5060impl YDeltaOut {
5061 fn insert(value: &Out, attrs: &Option<Box<Attrs>>) -> Self {
5062 let insert = Box::into_raw(Box::new(YOutput::from(value.clone())));
5063 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5064 let len = attrs.len() as u32;
5065 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5066 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5067 (len, attrs)
5068 } else {
5069 (0, null_mut())
5070 };
5071
5072 YDeltaOut {
5073 tag: Y_EVENT_CHANGE_ADD,
5074 len: 1,
5075 insert,
5076 attributes_len,
5077 attributes,
5078 }
5079 }
5080
5081 fn retain(len: u32, attrs: &Option<Box<Attrs>>) -> Self {
5082 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5083 let len = attrs.len() as u32;
5084 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5085 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5086 (len, attrs)
5087 } else {
5088 (0, null_mut())
5089 };
5090 YDeltaOut {
5091 tag: Y_EVENT_CHANGE_RETAIN,
5092 len,
5093 insert: null_mut(),
5094 attributes_len,
5095 attributes,
5096 }
5097 }
5098
5099 fn delete(len: u32) -> Self {
5100 YDeltaOut {
5101 tag: Y_EVENT_CHANGE_DELETE,
5102 len,
5103 insert: null_mut(),
5104 attributes_len: 0,
5105 attributes: null_mut(),
5106 }
5107 }
5108}
5109
5110impl<'a> From<&'a Delta> for YDeltaOut {
5111 fn from(d: &Delta) -> Self {
5112 match d {
5113 Delta::Inserted(value, attrs) => YDeltaOut::insert(value, attrs),
5114 Delta::Retain(len, attrs) => YDeltaOut::retain(*len, attrs),
5115 Delta::Deleted(len) => YDeltaOut::delete(*len),
5116 }
5117 }
5118}
5119
5120impl Drop for YDeltaOut {
5121 fn drop(&mut self) {
5122 unsafe {
5123 if !self.attributes.is_null() {
5124 let len = self.attributes_len as usize;
5125 drop(Vec::from_raw_parts(self.attributes, len, len));
5126 }
5127 if !self.insert.is_null() {
5128 drop(Box::from_raw(self.insert));
5129 }
5130 }
5131 }
5132}
5133
5134#[repr(C)]
5136pub struct YDeltaAttr {
5137 pub key: *const c_char,
5139 pub value: YOutput,
5141}
5142
5143impl YDeltaAttr {
5144 fn new(k: &Arc<str>, v: &Any) -> Self {
5145 let key = CString::new(k.as_ref()).unwrap().into_raw() as *const _;
5146 let value = YOutput::from(v);
5147 YDeltaAttr { key, value }
5148 }
5149}
5150
5151impl Drop for YDeltaAttr {
5152 fn drop(&mut self) {
5153 unsafe { ystring_destroy(self.key as *mut _) }
5154 }
5155}
5156
5157#[repr(C)]
5172pub struct YDeltaIn {
5173 pub tag: u8,
5183
5184 pub len: u32,
5187
5188 pub attributes: *const YInput,
5191
5192 pub insert: *const YInput,
5195}
5196
5197impl YDeltaIn {
5198 fn as_input(&self) -> Delta<YInput> {
5199 match self.tag {
5200 Y_EVENT_CHANGE_RETAIN => {
5201 let attrs = if self.attributes.is_null() {
5202 None
5203 } else {
5204 let attrs = unsafe { self.attributes.read() };
5205 map_attrs(attrs.into()).map(Box::new)
5206 };
5207 Delta::Retain(self.len, attrs)
5208 }
5209 Y_EVENT_CHANGE_DELETE => Delta::Deleted(self.len),
5210 Y_EVENT_CHANGE_ADD => {
5211 let attrs = if self.attributes.is_null() {
5212 None
5213 } else {
5214 let attrs = unsafe { self.attributes.read() };
5215 map_attrs(attrs.into()).map(Box::new)
5216 };
5217 let input = unsafe { self.insert.read() };
5218 Delta::Inserted(input, attrs)
5219 }
5220 tag => panic!("YDelta tag identifier is of unknown type: {}", tag),
5221 }
5222 }
5223}
5224
5225pub const Y_EVENT_KEY_CHANGE_ADD: c_char = 4;
5228
5229pub const Y_EVENT_KEY_CHANGE_DELETE: c_char = 5;
5232
5233pub const Y_EVENT_KEY_CHANGE_UPDATE: c_char = 6;
5236
5237#[repr(C)]
5250pub struct YEventKeyChange {
5251 pub key: *const c_char,
5253 pub tag: c_char,
5263
5264 pub old_value: *const YOutput,
5266
5267 pub new_value: *const YOutput,
5269}
5270
5271impl YEventKeyChange {
5272 fn new(key: &str, change: &EntryChange) -> Self {
5273 let key = CString::new(key).unwrap().into_raw() as *const _;
5274 match change {
5275 EntryChange::Inserted(new) => YEventKeyChange {
5276 key,
5277 tag: Y_EVENT_KEY_CHANGE_ADD,
5278 old_value: null(),
5279 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5280 },
5281 EntryChange::Updated(old, new) => YEventKeyChange {
5282 key,
5283 tag: Y_EVENT_KEY_CHANGE_UPDATE,
5284 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5285 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5286 },
5287 EntryChange::Removed(old) => YEventKeyChange {
5288 key,
5289 tag: Y_EVENT_KEY_CHANGE_DELETE,
5290 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5291 new_value: null(),
5292 },
5293 }
5294 }
5295}
5296
5297impl Drop for YEventKeyChange {
5298 fn drop(&mut self) {
5299 unsafe {
5300 ystring_destroy(self.key as *mut _);
5301 youtput_destroy(self.old_value as *mut _);
5302 youtput_destroy(self.new_value as *mut _);
5303 }
5304 }
5305}
5306
5307trait BranchPointable {
5308 fn into_raw_branch(self) -> *mut Branch;
5309 fn from_raw_branch(branch: *const Branch) -> Self;
5310}
5311
5312impl<T> BranchPointable for T
5313where
5314 T: AsRef<Branch> + From<BranchPtr>,
5315{
5316 fn into_raw_branch(self) -> *mut Branch {
5317 let branch_ref = self.as_ref();
5318 branch_ref as *const Branch as *mut Branch
5319 }
5320
5321 fn from_raw_branch(branch: *const Branch) -> Self {
5322 let b = unsafe { branch.as_ref().unwrap() };
5323 let branch_ref = BranchPtr::from(b);
5324 T::from(branch_ref)
5325 }
5326}
5327
5328#[repr(transparent)]
5339pub struct YStickyIndex(StickyIndex);
5340
5341impl From<StickyIndex> for YStickyIndex {
5342 #[inline(always)]
5343 fn from(value: StickyIndex) -> Self {
5344 YStickyIndex(value)
5345 }
5346}
5347
5348#[no_mangle]
5350pub unsafe extern "C" fn ysticky_index_destroy(pos: *mut YStickyIndex) {
5351 drop(Box::from_raw(pos))
5352}
5353
5354#[no_mangle]
5358pub unsafe extern "C" fn ysticky_index_assoc(pos: *const YStickyIndex) -> i8 {
5359 let pos = pos.as_ref().unwrap();
5360 match pos.0.assoc {
5361 Assoc::After => 0,
5362 Assoc::Before => -1,
5363 }
5364}
5365
5366#[no_mangle]
5373pub unsafe extern "C" fn ysticky_index_from_index(
5374 branch: *const Branch,
5375 txn: *mut Transaction,
5376 index: u32,
5377 assoc: i8,
5378) -> *mut YStickyIndex {
5379 assert!(!branch.is_null());
5380 assert!(!txn.is_null());
5381
5382 let branch = BranchPtr::from_raw_branch(branch);
5383 let txn = txn.as_mut().unwrap();
5384 let index = index as u32;
5385 let assoc = if assoc >= 0 {
5386 Assoc::After
5387 } else {
5388 Assoc::Before
5389 };
5390
5391 if let Some(txn) = txn.as_mut() {
5392 if let Some(pos) = StickyIndex::at(txn, branch, index, assoc) {
5393 Box::into_raw(Box::new(YStickyIndex(pos)))
5394 } else {
5395 null_mut()
5396 }
5397 } else {
5398 panic!("ysticky_index_from_index requires a read-write transaction");
5399 }
5400}
5401
5402#[no_mangle]
5405pub unsafe extern "C" fn ysticky_index_encode(
5406 pos: *const YStickyIndex,
5407 len: *mut u32,
5408) -> *mut c_char {
5409 let pos = pos.as_ref().unwrap();
5410 let binary = pos.0.encode_v1().into_boxed_slice();
5411 *len = binary.len() as u32;
5412 Box::into_raw(binary) as *mut c_char
5413}
5414
5415#[no_mangle]
5418pub unsafe extern "C" fn ysticky_index_decode(
5419 binary: *const c_char,
5420 len: u32,
5421) -> *mut YStickyIndex {
5422 let slice = std::slice::from_raw_parts(binary as *const u8, len as usize);
5423 if let Ok(pos) = StickyIndex::decode_v1(slice) {
5424 Box::into_raw(Box::new(YStickyIndex(pos)))
5425 } else {
5426 null_mut()
5427 }
5428}
5429
5430#[no_mangle]
5434pub unsafe extern "C" fn ysticky_index_to_json(pos: *const YStickyIndex) -> *mut c_char {
5435 let pos = pos.as_ref().unwrap();
5436 let json = match serde_json::to_string(&pos.0) {
5437 Ok(json) => json,
5438 Err(_) => return null_mut(),
5439 };
5440 CString::new(json).unwrap().into_raw()
5441}
5442
5443#[no_mangle]
5452pub unsafe extern "C" fn ysticky_index_from_json(json: *const c_char) -> *mut YStickyIndex {
5453 let cstr = CStr::from_ptr(json);
5454 let json = match cstr.to_str() {
5455 Ok(json) => json,
5456 Err(_) => return null_mut(),
5457 };
5458 match serde_json::from_str(json) {
5459 Ok(pos) => Box::into_raw(Box::new(YStickyIndex(pos))),
5460 Err(_) => null_mut(),
5461 }
5462}
5463
5464#[no_mangle]
5470pub unsafe extern "C" fn ysticky_index_read(
5471 pos: *const YStickyIndex,
5472 txn: *const Transaction,
5473 out_branch: *mut *mut Branch,
5474 out_index: *mut u32,
5475) {
5476 let pos = pos.as_ref().unwrap();
5477 let txn = txn.as_ref().unwrap();
5478
5479 if let Some(abs) = pos.0.get_offset(txn) {
5480 *out_branch = abs.branch.as_ref() as *const Branch as *mut Branch;
5481 *out_index = abs.index as u32;
5482 }
5483}
5484
5485pub type Weak = LinkSource;
5486
5487#[no_mangle]
5488pub unsafe extern "C" fn yweak_destroy(weak: *const Weak) {
5489 drop(Arc::from_raw(weak));
5490}
5491
5492#[no_mangle]
5493pub unsafe extern "C" fn yweak_deref(
5494 map_link: *const Branch,
5495 txn: *const Transaction,
5496) -> *mut YOutput {
5497 assert!(!map_link.is_null());
5498 assert!(!txn.is_null());
5499
5500 let txn = txn.as_ref().unwrap();
5501 let weak: WeakRef<MapRef> = WeakRef::from_raw_branch(map_link);
5502 if let Some(value) = weak.try_deref_value(txn) {
5503 Box::into_raw(Box::new(YOutput::from(value)))
5504 } else {
5505 null_mut()
5506 }
5507}
5508
5509#[no_mangle]
5510pub unsafe extern "C" fn yweak_iter(
5511 array_link: *const Branch,
5512 txn: *const Transaction,
5513) -> *mut WeakIter {
5514 assert!(!array_link.is_null());
5515 assert!(!txn.is_null());
5516
5517 let txn = txn.as_ref().unwrap();
5518 let weak: WeakRef<ArrayRef> = WeakRef::from_raw_branch(array_link);
5519 let iter: NativeUnquote<'static, Transaction> = std::mem::transmute(weak.unquote(txn));
5520
5521 Box::into_raw(Box::new(WeakIter(iter)))
5522}
5523
5524#[no_mangle]
5525pub unsafe extern "C" fn yweak_iter_destroy(iter: *mut WeakIter) {
5526 drop(Box::from_raw(iter))
5527}
5528
5529#[no_mangle]
5530pub unsafe extern "C" fn yweak_iter_next(iter: *mut WeakIter) -> *mut YOutput {
5531 assert!(!iter.is_null());
5532 let iter = iter.as_mut().unwrap();
5533
5534 if let Some(value) = iter.0.next() {
5535 Box::into_raw(Box::new(YOutput::from(value)))
5536 } else {
5537 null_mut()
5538 }
5539}
5540
5541#[no_mangle]
5542pub unsafe extern "C" fn yweak_string(
5543 text_link: *const Branch,
5544 txn: *const Transaction,
5545) -> *mut c_char {
5546 assert!(!text_link.is_null());
5547 assert!(!txn.is_null());
5548
5549 let txn = txn.as_ref().unwrap();
5550 let weak: WeakRef<TextRef> = WeakRef::from_raw_branch(text_link);
5551
5552 let str = weak.get_string(txn);
5553 CString::new(str).unwrap().into_raw()
5554}
5555
5556#[no_mangle]
5557pub unsafe extern "C" fn yweak_xml_string(
5558 xml_text_link: *const Branch,
5559 txn: *const Transaction,
5560) -> *mut c_char {
5561 assert!(!xml_text_link.is_null());
5562 assert!(!txn.is_null());
5563
5564 let txn = txn.as_ref().unwrap();
5565 let weak: WeakRef<XmlTextRef> = WeakRef::from_raw_branch(xml_text_link);
5566
5567 let str = weak.get_string(txn);
5568 CString::new(str).unwrap().into_raw()
5569}
5570
5571#[no_mangle]
5576pub unsafe extern "C" fn yweak_observe(
5577 weak: *const Branch,
5578 state: *mut c_void,
5579 cb: extern "C" fn(*mut c_void, *const YWeakLinkEvent),
5580) -> *mut Subscription {
5581 assert!(!weak.is_null());
5582
5583 let state = CallbackState::new(state);
5584 let txt: WeakRef<BranchPtr> = WeakRef::from_raw_branch(weak);
5585 let subscription = txt.observe(move |txn, e| {
5586 let e = YWeakLinkEvent::new(e, txn);
5587 cb(state.0, &e as *const YWeakLinkEvent);
5588 });
5589 Box::into_raw(Box::new(subscription))
5590}
5591
5592#[no_mangle]
5593pub unsafe extern "C" fn ymap_link(
5594 map: *const Branch,
5595 txn: *const Transaction,
5596 key: *const c_char,
5597) -> *const Weak {
5598 assert!(!map.is_null());
5599 assert!(!txn.is_null());
5600
5601 let txn = txn.as_ref().unwrap();
5602 let map = MapRef::from_raw_branch(map);
5603 let key = CStr::from_ptr(key).to_str().unwrap();
5604 if let Some(weak) = map.link(txn, key) {
5605 let source = weak.source();
5606 Arc::into_raw(source.clone())
5607 } else {
5608 null()
5609 }
5610}
5611
5612#[no_mangle]
5613pub unsafe extern "C" fn ytext_quote(
5614 text: *const Branch,
5615 txn: *mut Transaction,
5616 start_index: u32,
5617 end_index: u32,
5618 start_exclusive: i8,
5619 end_exclusive: i8,
5620) -> *const Weak {
5621 assert!(!text.is_null());
5622 assert!(!txn.is_null());
5623
5624 let text = TextRef::from_raw_branch(text);
5625 let txn = txn.as_mut().unwrap();
5626 let txn = txn
5627 .as_mut()
5628 .expect("provided transaction was not writeable");
5629
5630 let range = ExplicitRange {
5631 start_index,
5632 end_index,
5633 start_exclusive,
5634 end_exclusive,
5635 };
5636 if let Ok(weak) = text.quote(txn, range) {
5637 let source = weak.source();
5638 Arc::into_raw(source.clone())
5639 } else {
5640 null()
5641 }
5642}
5643
5644#[no_mangle]
5645pub unsafe extern "C" fn yarray_quote(
5646 array: *const Branch,
5647 txn: *mut Transaction,
5648 start_index: u32,
5649 end_index: u32,
5650 start_exclusive: i8,
5651 end_exclusive: i8,
5652) -> *const Weak {
5653 assert!(!array.is_null());
5654 assert!(!txn.is_null());
5655
5656 let array = ArrayRef::from_raw_branch(array);
5657 let txn = txn.as_mut().unwrap();
5658 let txn = txn
5659 .as_mut()
5660 .expect("provided transaction was not writeable");
5661
5662 let range = ExplicitRange {
5663 start_index,
5664 end_index,
5665 start_exclusive,
5666 end_exclusive,
5667 };
5668 if let Ok(weak) = array.quote(txn, range) {
5669 let source = weak.source();
5670 Arc::into_raw(source.clone())
5671 } else {
5672 null()
5673 }
5674}
5675
5676struct ExplicitRange {
5677 start_index: u32,
5678 end_index: u32,
5679 start_exclusive: i8,
5680 end_exclusive: i8,
5681}
5682
5683impl RangeBounds<u32> for ExplicitRange {
5684 fn start_bound(&self) -> Bound<&u32> {
5685 if self.start_exclusive == 0 {
5686 Bound::Included(&self.start_index)
5687 } else {
5688 Bound::Excluded(&self.start_index)
5689 }
5690 }
5691
5692 fn end_bound(&self) -> Bound<&u32> {
5693 if self.end_exclusive == 0 {
5694 Bound::Included(&self.end_index)
5695 } else {
5696 Bound::Excluded(&self.end_index)
5697 }
5698 }
5699}
5700
5701#[repr(C)]
5709pub struct YBranchId {
5710 pub client_or_len: i64,
5713 pub variant: YBranchIdVariant,
5714}
5715
5716#[repr(C)]
5717pub union YBranchIdVariant {
5718 pub clock: u32,
5720 pub name: *const u8,
5725}
5726
5727#[no_mangle]
5730pub unsafe extern "C" fn ybranch_id(branch: *const Branch) -> YBranchId {
5731 let branch = branch.as_ref().unwrap();
5732 match branch.id() {
5733 BranchID::Nested(id) => YBranchId {
5734 client_or_len: id.client as i64,
5735 variant: YBranchIdVariant { clock: id.clock },
5736 },
5737 BranchID::Root(name) => {
5738 let len = -(name.len() as i64);
5739 YBranchId {
5740 client_or_len: len,
5741 variant: YBranchIdVariant {
5742 name: name.as_ptr(),
5743 },
5744 }
5745 }
5746 }
5747}
5748
5749#[no_mangle]
5755pub unsafe extern "C" fn ybranch_get(
5756 branch_id: *const YBranchId,
5757 txn: *mut Transaction,
5758) -> *mut Branch {
5759 let txn = txn.as_ref().unwrap();
5760 let branch_id = branch_id.as_ref().unwrap();
5761 let client_or_len = branch_id.client_or_len;
5762 let ptr = if client_or_len >= 0 {
5763 BranchID::get_nested(txn, &ID::new(client_or_len as u64, branch_id.variant.clock))
5764 } else {
5765 let name = std::slice::from_raw_parts(branch_id.variant.name, (-client_or_len) as usize);
5766 BranchID::get_root(txn, std::str::from_utf8_unchecked(name))
5767 };
5768
5769 match ptr {
5770 None => null_mut(),
5771 Some(branch_ptr) => branch_ptr.into_raw_branch(),
5772 }
5773}
5774
5775#[no_mangle]
5779pub unsafe extern "C" fn ybranch_alive(branch: *mut Branch) -> u8 {
5780 if branch.is_null() {
5781 Y_FALSE
5782 } else {
5783 let branch = BranchPtr::from_raw_branch(branch);
5784 if branch.is_deleted() {
5785 Y_FALSE
5786 } else {
5787 Y_TRUE
5788 }
5789 }
5790}
5791
5792#[no_mangle]
5799pub unsafe extern "C" fn ybranch_json(branch: *mut Branch, txn: *mut Transaction) -> *mut c_char {
5800 if branch.is_null() {
5801 std::ptr::null_mut()
5802 } else {
5803 let txn = txn.as_ref().unwrap();
5804 let branch_ref = BranchPtr::from_raw_branch(branch);
5805 let any = match branch_ref.type_ref() {
5806 TypeRef::Array => ArrayRef::from_raw_branch(branch).to_json(txn),
5807 TypeRef::Map => MapRef::from_raw_branch(branch).to_json(txn),
5808 TypeRef::Text => TextRef::from_raw_branch(branch).get_string(txn).into(),
5809 TypeRef::XmlElement(_) => XmlElementRef::from_raw_branch(branch)
5810 .get_string(txn)
5811 .into(),
5812 TypeRef::XmlFragment => XmlFragmentRef::from_raw_branch(branch)
5813 .get_string(txn)
5814 .into(),
5815 TypeRef::XmlText => XmlTextRef::from_raw_branch(branch).get_string(txn).into(),
5816 TypeRef::SubDoc | TypeRef::XmlHook | TypeRef::WeakLink(_) | TypeRef::Undefined => {
5817 return std::ptr::null_mut()
5818 }
5819 };
5820 let json = match serde_json::to_string(&any) {
5821 Ok(json) => json,
5822 Err(_) => return std::ptr::null_mut(),
5823 };
5824 CString::new(json).unwrap().into_raw()
5825 }
5826}