1use std::collections::{Bound, HashMap};
2use std::ffi::{c_char, c_void, CStr, CString};
3use std::mem::{forget, ManuallyDrop, MaybeUninit};
4use std::ops::{Deref, RangeBounds};
5use std::ptr::{null, null_mut};
6use std::sync::atomic::{AtomicPtr, Ordering};
7use std::sync::Arc;
8use yrs::block::{ClientID, EmbedPrelim, ItemContent, Prelim, Unused};
9use yrs::branch::BranchPtr;
10use yrs::encoding::read::Error;
11use yrs::error::UpdateError;
12use yrs::json_path::JsonPathIter as NativeJsonPathIter;
13use yrs::types::array::ArrayEvent;
14use yrs::types::array::ArrayIter as NativeArrayIter;
15use yrs::types::map::MapEvent;
16use yrs::types::map::MapIter as NativeMapIter;
17use yrs::types::text::{Diff, TextEvent, YChange};
18use yrs::types::weak::{LinkSource, Unquote as NativeUnquote, WeakEvent, WeakRef};
19use yrs::types::xml::{Attributes as NativeAttributes, XmlOut};
20use yrs::types::xml::{TreeWalker as NativeTreeWalker, XmlFragment};
21use yrs::types::xml::{XmlEvent, XmlTextEvent};
22use yrs::types::{Attrs, Change, Delta, EntryChange, Event, PathSegment, ToJson, TypeRef};
23use yrs::undo::EventKind;
24use yrs::updates::decoder::{Decode, DecoderV1};
25use yrs::updates::encoder::{Encode, Encoder, EncoderV1, EncoderV2};
26use yrs::{
27 uuid_v4, Any, Array, ArrayRef, Assoc, BranchID, DeleteSet, GetString, JsonPath, JsonPathEval,
28 Map, MapRef, Observable, OffsetKind, Options, Origin, Out, Quotable, ReadTxn, Snapshot,
29 StateVector, StickyIndex, Store, SubdocsEvent, SubdocsEventIter, Text, TextRef, Transact,
30 TransactionCleanupEvent, Update, Xml, XmlElementPrelim, XmlElementRef, XmlFragmentRef,
31 XmlTextPrelim, XmlTextRef, ID,
32};
33
34pub const Y_JSON: i8 = -9;
37
38pub const Y_JSON_BOOL: i8 = -8;
40
41pub const Y_JSON_NUM: i8 = -7;
43
44pub const Y_JSON_INT: i8 = -6;
46
47pub const Y_JSON_STR: i8 = -5;
49
50pub const Y_JSON_BUF: i8 = -4;
52
53pub const Y_JSON_ARR: i8 = -3;
56
57pub const Y_JSON_MAP: i8 = -2;
60
61pub const Y_JSON_NULL: i8 = -1;
63
64pub const Y_JSON_UNDEF: i8 = 0;
66
67pub const Y_ARRAY: i8 = 1;
69
70pub const Y_MAP: i8 = 2;
72
73pub const Y_TEXT: i8 = 3;
75
76pub const Y_XML_ELEM: i8 = 4;
78
79pub const Y_XML_TEXT: i8 = 5;
81
82pub const Y_XML_FRAG: i8 = 6;
84
85pub const Y_DOC: i8 = 7;
87
88pub const Y_WEAK_LINK: i8 = 8;
90
91pub const Y_UNDEFINED: i8 = 9;
94
95pub const Y_TRUE: u8 = 1;
97
98pub const Y_FALSE: u8 = 0;
100
101pub const Y_OFFSET_BYTES: u8 = 0;
104
105pub const Y_OFFSET_UTF16: u8 = 1;
108
109pub type Doc = yrs::Doc;
119
120pub type Branch = yrs::branch::Branch;
128
129pub type Subscription = yrs::Subscription;
133
134#[repr(transparent)]
136pub struct ArrayIter(NativeArrayIter<&'static Transaction, Transaction>);
137
138#[repr(transparent)]
140pub struct WeakIter(NativeUnquote<'static, Transaction>);
141
142#[repr(transparent)]
145pub struct MapIter(NativeMapIter<'static, &'static Transaction, Transaction>);
146
147#[repr(transparent)]
151pub struct Attributes(NativeAttributes<'static, &'static Transaction, Transaction>);
152
153#[repr(transparent)]
158pub struct TreeWalker(NativeTreeWalker<'static, &'static Transaction, Transaction>);
159
160#[repr(transparent)]
164pub struct Transaction(TransactionInner);
165
166#[repr(C)]
168pub struct JsonPathIter {
169 query: String,
170 json_path: Box<JsonPath<'static>>,
171 inner: NativeJsonPathIter<'static, Transaction>,
172}
173
174enum TransactionInner {
175 ReadOnly(yrs::Transaction<'static>),
176 ReadWrite(yrs::TransactionMut<'static>),
177}
178
179impl Transaction {
180 fn read_only(txn: yrs::Transaction) -> Self {
181 Transaction(TransactionInner::ReadOnly(unsafe {
182 std::mem::transmute(txn)
183 }))
184 }
185
186 fn read_write(txn: yrs::TransactionMut) -> Self {
187 Transaction(TransactionInner::ReadWrite(unsafe {
188 std::mem::transmute(txn)
189 }))
190 }
191
192 fn is_writeable(&self) -> bool {
193 match &self.0 {
194 TransactionInner::ReadOnly(_) => false,
195 TransactionInner::ReadWrite(_) => true,
196 }
197 }
198
199 fn as_mut(&mut self) -> Option<&mut yrs::TransactionMut<'static>> {
200 match &mut self.0 {
201 TransactionInner::ReadOnly(_) => None,
202 TransactionInner::ReadWrite(txn) => Some(txn),
203 }
204 }
205}
206
207impl ReadTxn for Transaction {
208 fn store(&self) -> &Store {
209 match &self.0 {
210 TransactionInner::ReadOnly(txn) => txn.store(),
211 TransactionInner::ReadWrite(txn) => txn.store(),
212 }
213 }
214}
215
216#[repr(C)]
219pub struct YMapEntry {
220 pub key: *const c_char,
222 pub value: *const YOutput,
225}
226
227impl YMapEntry {
228 fn new(key: &str, value: Box<YOutput>) -> Self {
229 let key = CString::new(key).unwrap().into_raw();
230 let value = Box::into_raw(value) as *const YOutput;
231 YMapEntry { key, value }
232 }
233}
234
235impl Drop for YMapEntry {
236 fn drop(&mut self) {
237 unsafe {
238 drop(CString::from_raw(self.key as *mut c_char));
239 drop(Box::from_raw(self.value as *mut YOutput));
240 }
241 }
242}
243
244#[repr(C)]
247pub struct YXmlAttr {
248 pub name: *const c_char,
249 pub value: *const YOutput,
250}
251
252impl Drop for YXmlAttr {
253 fn drop(&mut self) {
254 unsafe {
255 drop(CString::from_raw(self.name as *mut _));
256 drop(CString::from_raw(self.value as *mut _));
257 }
258 }
259}
260
261#[repr(C)]
263pub struct YOptions {
264 pub id: u64,
271
272 pub guid: *const c_char,
275
276 pub collection_id: *const c_char,
279
280 pub encoding: u8,
286
287 pub skip_gc: u8,
290
291 pub auto_load: u8,
294
295 pub should_load: u8,
297}
298
299impl Into<Options> for YOptions {
300 fn into(self) -> Options {
301 let encoding = match self.encoding {
302 Y_OFFSET_BYTES => OffsetKind::Bytes,
303 Y_OFFSET_UTF16 => OffsetKind::Utf16,
304 _ => panic!("Unrecognized YOptions.encoding type"),
305 };
306 let guid = if self.guid.is_null() {
307 uuid_v4()
308 } else {
309 let c_str = unsafe { CStr::from_ptr(self.guid) };
310 let str = c_str.to_str().unwrap();
311 str.into()
312 };
313 let collection_id = if self.collection_id.is_null() {
314 None
315 } else {
316 let c_str = unsafe { CStr::from_ptr(self.collection_id) };
317 let str = Arc::from(c_str.to_str().unwrap());
318 Some(str)
319 };
320 Options {
321 client_id: self.id as ClientID,
322 guid,
323 collection_id,
324 skip_gc: if self.skip_gc == 0 { false } else { true },
325 auto_load: if self.auto_load == 0 { false } else { true },
326 should_load: if self.should_load == 0 { false } else { true },
327 offset_kind: encoding,
328 }
329 }
330}
331
332impl From<Options> for YOptions {
333 fn from(o: Options) -> Self {
334 YOptions {
335 id: o.client_id,
336 guid: CString::new(o.guid.as_ref()).unwrap().into_raw(),
337 collection_id: if let Some(collection_id) = o.collection_id {
338 CString::new(collection_id.to_string()).unwrap().into_raw()
339 } else {
340 null_mut()
341 },
342 encoding: match o.offset_kind {
343 OffsetKind::Bytes => Y_OFFSET_BYTES,
344 OffsetKind::Utf16 => Y_OFFSET_UTF16,
345 },
346 skip_gc: if o.skip_gc { 1 } else { 0 },
347 auto_load: if o.auto_load { 1 } else { 0 },
348 should_load: if o.should_load { 1 } else { 0 },
349 }
350 }
351}
352
353#[no_mangle]
355pub unsafe extern "C" fn yoptions() -> YOptions {
356 Options::default().into()
357}
358
359#[no_mangle]
361pub unsafe extern "C" fn ydoc_destroy(value: *mut Doc) {
362 if !value.is_null() {
363 drop(Box::from_raw(value));
364 }
365}
366
367#[no_mangle]
369pub unsafe extern "C" fn ymap_entry_destroy(value: *mut YMapEntry) {
370 if !value.is_null() {
371 drop(Box::from_raw(value));
372 }
373}
374
375#[no_mangle]
377pub unsafe extern "C" fn yxmlattr_destroy(attr: *mut YXmlAttr) {
378 if !attr.is_null() {
379 drop(Box::from_raw(attr));
380 }
381}
382
383#[no_mangle]
386pub unsafe extern "C" fn ystring_destroy(str: *mut c_char) {
387 if !str.is_null() {
388 drop(CString::from_raw(str));
389 }
390}
391
392#[no_mangle]
397pub unsafe extern "C" fn ybinary_destroy(ptr: *mut c_char, len: u32) {
398 if !ptr.is_null() {
399 drop(Vec::from_raw_parts(ptr, len as usize, len as usize));
400 }
401}
402
403#[no_mangle]
407pub extern "C" fn ydoc_new() -> *mut Doc {
408 Box::into_raw(Box::new(Doc::new()))
409}
410
411#[no_mangle]
417pub unsafe extern "C" fn ydoc_clone(doc: *mut Doc) -> *mut Doc {
418 let doc = doc.as_mut().unwrap();
419 Box::into_raw(Box::new(doc.clone()))
420}
421
422#[no_mangle]
426pub extern "C" fn ydoc_new_with_options(options: YOptions) -> *mut Doc {
427 Box::into_raw(Box::new(Doc::with_options(options.into())))
428}
429
430#[no_mangle]
432pub unsafe extern "C" fn ydoc_id(doc: *mut Doc) -> u64 {
433 let doc = doc.as_ref().unwrap();
434 doc.client_id()
435}
436
437#[no_mangle]
441pub unsafe extern "C" fn ydoc_guid(doc: *mut Doc) -> *mut c_char {
442 let doc = doc.as_ref().unwrap();
443 let uid = doc.guid();
444 CString::new(uid.as_ref()).unwrap().into_raw()
445}
446
447#[no_mangle]
452pub unsafe extern "C" fn ydoc_collection_id(doc: *mut Doc) -> *mut c_char {
453 let doc = doc.as_ref().unwrap();
454 if let Some(cid) = doc.collection_id() {
455 CString::new(cid.as_ref()).unwrap().into_raw()
456 } else {
457 null_mut()
458 }
459}
460
461#[no_mangle]
464pub unsafe extern "C" fn ydoc_should_load(doc: *mut Doc) -> u8 {
465 let doc = doc.as_ref().unwrap();
466 doc.should_load() as u8
467}
468
469#[no_mangle]
472pub unsafe extern "C" fn ydoc_auto_load(doc: *mut Doc) -> u8 {
473 let doc = doc.as_ref().unwrap();
474 doc.auto_load() as u8
475}
476
477#[repr(transparent)]
478struct CallbackState(*mut c_void);
479
480unsafe impl Send for CallbackState {}
481unsafe impl Sync for CallbackState {}
482
483impl CallbackState {
484 #[inline]
485 fn new(state: *mut c_void) -> Self {
486 CallbackState(state)
487 }
488}
489
490#[no_mangle]
491pub unsafe extern "C" fn ydoc_observe_updates_v1(
492 doc: *mut Doc,
493 state: *mut c_void,
494 cb: extern "C" fn(*mut c_void, u32, *const c_char),
495) -> *mut Subscription {
496 let state = CallbackState::new(state);
497 let doc = doc.as_ref().unwrap();
498 let subscription = doc
499 .observe_update_v1(move |_, e| {
500 let bytes = &e.update;
501 let len = bytes.len() as u32;
502 cb(state.0, len, bytes.as_ptr() as *const c_char)
503 })
504 .unwrap();
505 Box::into_raw(Box::new(subscription))
506}
507
508#[no_mangle]
509pub unsafe extern "C" fn ydoc_observe_updates_v2(
510 doc: *mut Doc,
511 state: *mut c_void,
512 cb: extern "C" fn(*mut c_void, u32, *const c_char),
513) -> *mut Subscription {
514 let state = CallbackState::new(state);
515 let doc = doc.as_ref().unwrap();
516 let subscription = doc
517 .observe_update_v2(move |_, e| {
518 let bytes = &e.update;
519 let len = bytes.len() as u32;
520 cb(state.0, len, bytes.as_ptr() as *const c_char)
521 })
522 .unwrap();
523 Box::into_raw(Box::new(subscription))
524}
525
526#[no_mangle]
527pub unsafe extern "C" fn ydoc_observe_after_transaction(
528 doc: *mut Doc,
529 state: *mut c_void,
530 cb: extern "C" fn(*mut c_void, *mut YAfterTransactionEvent),
531) -> *mut Subscription {
532 let state = CallbackState::new(state);
533 let doc = doc.as_ref().unwrap();
534 let subscription = doc
535 .observe_transaction_cleanup(move |_, e| {
536 let mut event = YAfterTransactionEvent::new(e);
537 cb(state.0, (&mut event) as *mut _);
538 })
539 .unwrap();
540 Box::into_raw(Box::new(subscription))
541}
542
543#[no_mangle]
544pub unsafe extern "C" fn ydoc_observe_subdocs(
545 doc: *mut Doc,
546 state: *mut c_void,
547 cb: extern "C" fn(*mut c_void, *mut YSubdocsEvent),
548) -> *mut Subscription {
549 let state = CallbackState::new(state);
550 let doc = doc.as_mut().unwrap();
551 let subscription = doc
552 .observe_subdocs(move |_, e| {
553 let mut event = YSubdocsEvent::new(e);
554 cb(state.0, (&mut event) as *mut _);
555 })
556 .unwrap();
557 Box::into_raw(Box::new(subscription))
558}
559
560#[no_mangle]
561pub unsafe extern "C" fn ydoc_observe_clear(
562 doc: *mut Doc,
563 state: *mut c_void,
564 cb: extern "C" fn(*mut c_void, *mut Doc),
565) -> *mut Subscription {
566 let state = CallbackState::new(state);
567 let doc = doc.as_mut().unwrap();
568 let subscription = doc
569 .observe_destroy(move |_, e| cb(state.0, e as *const Doc as *mut _))
570 .unwrap();
571 Box::into_raw(Box::new(subscription))
572}
573
574#[no_mangle]
576pub unsafe extern "C" fn ydoc_load(doc: *mut Doc, parent_txn: *mut Transaction) {
577 let doc = doc.as_ref().unwrap();
578 let txn = parent_txn.as_mut().unwrap();
579 if let Some(txn) = txn.as_mut() {
580 doc.load(txn)
581 } else {
582 panic!("ydoc_load: passed read-only parent transaction, where read-write one was expected")
583 }
584}
585
586#[no_mangle]
589pub unsafe extern "C" fn ydoc_clear(doc: *mut Doc, parent_txn: *mut Transaction) {
590 let doc = doc.as_mut().unwrap();
591 let txn = parent_txn.as_mut().unwrap();
592 if let Some(txn) = txn.as_mut() {
593 doc.destroy(txn)
594 } else {
595 panic!("ydoc_clear: passed read-only parent transaction, where read-write one was expected")
596 }
597}
598
599#[no_mangle]
606pub unsafe extern "C" fn ydoc_read_transaction(doc: *mut Doc) -> *mut Transaction {
607 assert!(!doc.is_null());
608
609 let doc = doc.as_mut().unwrap();
610 if let Ok(txn) = doc.try_transact() {
611 Box::into_raw(Box::new(Transaction::read_only(txn)))
612 } else {
613 null_mut()
614 }
615}
616
617#[no_mangle]
629pub unsafe extern "C" fn ydoc_write_transaction(
630 doc: *mut Doc,
631 origin_len: u32,
632 origin: *const c_char,
633) -> *mut Transaction {
634 assert!(!doc.is_null());
635
636 let doc = doc.as_mut().unwrap();
637 if origin_len == 0 {
638 if let Ok(txn) = doc.try_transact_mut() {
639 Box::into_raw(Box::new(Transaction::read_write(txn)))
640 } else {
641 null_mut()
642 }
643 } else {
644 let origin = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
645 if let Ok(txn) = doc.try_transact_mut_with(origin) {
646 Box::into_raw(Box::new(Transaction::read_write(txn)))
647 } else {
648 null_mut()
649 }
650 }
651}
652
653#[no_mangle]
655pub unsafe extern "C" fn ytransaction_subdocs(
656 txn: *mut Transaction,
657 len: *mut u32,
658) -> *mut *mut Doc {
659 let txn = txn.as_ref().unwrap();
660 let subdocs: Vec<_> = txn
661 .subdocs()
662 .map(|doc| doc as *const Doc as *mut Doc)
663 .collect();
664 let out = subdocs.into_boxed_slice();
665 *len = out.len() as u32;
666 Box::into_raw(out) as *mut _
667}
668
669#[no_mangle]
673pub unsafe extern "C" fn ytransaction_commit(txn: *mut Transaction) {
674 assert!(!txn.is_null());
675 drop(Box::from_raw(txn)); }
677
678#[no_mangle]
682pub unsafe extern "C" fn ytransaction_force_gc(txn: *mut Transaction) {
683 assert!(!txn.is_null());
684 let txn = txn.as_mut().unwrap();
685 let txn = txn.as_mut().unwrap();
686 txn.gc(None);
687}
688
689#[no_mangle]
692pub unsafe extern "C" fn ytransaction_writeable(txn: *mut Transaction) -> u8 {
693 assert!(!txn.is_null());
694 if txn.as_ref().unwrap().is_writeable() {
695 1
696 } else {
697 0
698 }
699}
700
701#[no_mangle]
722pub unsafe extern "C" fn ytransaction_json_path(
723 txn: *mut Transaction,
724 json_path: *const c_char,
725) -> *mut JsonPathIter {
726 assert!(!txn.is_null());
727 let txn = txn.as_ref().unwrap();
728
729 let query: String = CStr::from_ptr(json_path).to_str().unwrap().into();
731 let json_path: &'static str = unsafe { std::mem::transmute(query.as_str()) };
733 let json_path = match JsonPath::parse(json_path) {
734 Ok(query) => Box::new(query),
735 Err(_) => return null_mut(),
736 };
737 let json_path_ref: &'static JsonPath = unsafe { std::mem::transmute(json_path.as_ref()) };
739 let inner = txn.json_path(json_path_ref);
740 let iter = Box::new(JsonPathIter {
741 query,
742 json_path,
743 inner,
744 });
745 Box::into_raw(iter)
746}
747
748#[no_mangle]
750pub unsafe extern "C" fn yjson_path_iter_next(iter: *mut JsonPathIter) -> *mut YOutput {
751 assert!(!iter.is_null());
752 let iter = iter.as_mut().unwrap();
753 if let Some(value) = iter.inner.next() {
754 let youtput = YOutput::from(value);
755 Box::into_raw(Box::new(youtput))
756 } else {
757 null_mut()
758 }
759}
760
761#[no_mangle]
763pub unsafe extern "C" fn yjson_path_iter_destroy(iter: *mut JsonPathIter) {
764 if !iter.is_null() {
765 drop(Box::from_raw(iter));
766 }
767}
768
769#[no_mangle]
775pub unsafe extern "C" fn ytype_get(txn: *mut Transaction, name: *const c_char) -> *mut Branch {
776 assert!(!txn.is_null());
777 assert!(!name.is_null());
778
779 let name = CStr::from_ptr(name).to_str().unwrap();
780 if let Some(txt) = txn.as_mut().unwrap().get_text(name) {
783 txt.into_raw_branch()
784 } else {
785 null_mut()
786 }
787}
788
789#[no_mangle]
793pub unsafe extern "C" fn ytext(doc: *mut Doc, name: *const c_char) -> *mut Branch {
794 assert!(!doc.is_null());
795 assert!(!name.is_null());
796
797 let name = CStr::from_ptr(name).to_str().unwrap();
798 let txt = doc.as_mut().unwrap().get_or_insert_text(name);
799 txt.into_raw_branch()
800}
801
802#[no_mangle]
808pub unsafe extern "C" fn yarray(doc: *mut Doc, name: *const c_char) -> *mut Branch {
809 assert!(!doc.is_null());
810 assert!(!name.is_null());
811
812 let name = CStr::from_ptr(name).to_str().unwrap();
813 doc.as_mut()
814 .unwrap()
815 .get_or_insert_array(name)
816 .into_raw_branch()
817}
818
819#[no_mangle]
825pub unsafe extern "C" fn ymap(doc: *mut Doc, name: *const c_char) -> *mut Branch {
826 assert!(!doc.is_null());
827 assert!(!name.is_null());
828
829 let name = CStr::from_ptr(name).to_str().unwrap();
830 doc.as_mut()
831 .unwrap()
832 .get_or_insert_map(name)
833 .into_raw_branch()
834}
835
836#[no_mangle]
840pub unsafe extern "C" fn yxmlfragment(doc: *mut Doc, name: *const c_char) -> *mut Branch {
841 assert!(!doc.is_null());
842 assert!(!name.is_null());
843
844 let name = CStr::from_ptr(name).to_str().unwrap();
845 doc.as_mut()
846 .unwrap()
847 .get_or_insert_xml_fragment(name)
848 .into_raw_branch()
849}
850
851#[no_mangle]
861pub unsafe extern "C" fn ytransaction_state_vector_v1(
862 txn: *const Transaction,
863 len: *mut u32,
864) -> *mut c_char {
865 assert!(!txn.is_null());
866
867 let txn = txn.as_ref().unwrap();
868 let state_vector = txn.state_vector();
869 let binary = state_vector.encode_v1().into_boxed_slice();
870
871 *len = binary.len() as u32;
872 Box::into_raw(binary) as *mut c_char
873}
874
875#[no_mangle]
890pub unsafe extern "C" fn ytransaction_state_diff_v1(
891 txn: *const Transaction,
892 sv: *const c_char,
893 sv_len: u32,
894 len: *mut u32,
895) -> *mut c_char {
896 assert!(!txn.is_null());
897
898 let txn = txn.as_ref().unwrap();
899 let sv = {
900 if sv.is_null() {
901 StateVector::default()
902 } else {
903 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
904 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
905 sv
906 } else {
907 return null_mut();
908 }
909 }
910 };
911
912 let mut encoder = EncoderV1::new();
913 txn.encode_diff(&sv, &mut encoder);
914 let binary = encoder.to_vec().into_boxed_slice();
915 *len = binary.len() as u32;
916 Box::into_raw(binary) as *mut c_char
917}
918
919#[no_mangle]
934pub unsafe extern "C" fn ytransaction_state_diff_v2(
935 txn: *const Transaction,
936 sv: *const c_char,
937 sv_len: u32,
938 len: *mut u32,
939) -> *mut c_char {
940 assert!(!txn.is_null());
941
942 let txn = txn.as_ref().unwrap();
943 let sv = {
944 if sv.is_null() {
945 StateVector::default()
946 } else {
947 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
948 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
949 sv
950 } else {
951 return null_mut();
952 }
953 }
954 };
955
956 let mut encoder = EncoderV2::new();
957 txn.encode_diff(&sv, &mut encoder);
958 let binary = encoder.to_vec().into_boxed_slice();
959 *len = binary.len() as u32;
960 Box::into_raw(binary) as *mut c_char
961}
962
963#[no_mangle]
967pub unsafe extern "C" fn ytransaction_snapshot(
968 txn: *const Transaction,
969 len: *mut u32,
970) -> *mut c_char {
971 assert!(!txn.is_null());
972 let txn = txn.as_ref().unwrap();
973 let binary = txn.snapshot().encode_v1().into_boxed_slice();
974
975 *len = binary.len() as u32;
976 Box::into_raw(binary) as *mut c_char
977}
978
979#[no_mangle]
988pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v1(
989 txn: *const Transaction,
990 snapshot: *const c_char,
991 snapshot_len: u32,
992 len: *mut u32,
993) -> *mut c_char {
994 assert!(!txn.is_null());
995 let txn = txn.as_ref().unwrap();
996 let snapshot = {
997 let len = snapshot_len as usize;
998 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
999 Snapshot::decode_v1(&data).unwrap()
1000 };
1001 let mut encoder = EncoderV1::new();
1002 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
1003 Err(_) => null_mut(),
1004 Ok(_) => {
1005 let binary = encoder.to_vec().into_boxed_slice();
1006 *len = binary.len() as u32;
1007 Box::into_raw(binary) as *mut c_char
1008 }
1009 }
1010}
1011
1012#[no_mangle]
1021pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v2(
1022 txn: *const Transaction,
1023 snapshot: *const c_char,
1024 snapshot_len: u32,
1025 len: *mut u32,
1026) -> *mut c_char {
1027 assert!(!txn.is_null());
1028 let txn = txn.as_ref().unwrap();
1029 let snapshot = {
1030 let len = snapshot_len as usize;
1031 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
1032 Snapshot::decode_v1(&data).unwrap()
1033 };
1034 let mut encoder = EncoderV2::new();
1035 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
1036 Err(_) => null_mut(),
1037 Ok(_) => {
1038 let binary = encoder.to_vec().into_boxed_slice();
1039 *len = binary.len() as u32;
1040 Box::into_raw(binary) as *mut c_char
1041 }
1042 }
1043}
1044
1045#[no_mangle]
1051pub unsafe extern "C" fn ytransaction_pending_ds(txn: *const Transaction) -> *mut YDeleteSet {
1052 let txn = txn.as_ref().unwrap();
1053 match txn.store().pending_ds() {
1054 None => null_mut(),
1055 Some(ds) => Box::into_raw(Box::new(YDeleteSet::new(ds))),
1056 }
1057}
1058
1059#[no_mangle]
1060pub unsafe extern "C" fn ydelete_set_destroy(ds: *mut YDeleteSet) {
1061 if ds.is_null() {
1062 return;
1063 }
1064 drop(Box::from_raw(ds))
1065}
1066
1067#[no_mangle]
1076pub unsafe extern "C" fn ytransaction_pending_update(
1077 txn: *const Transaction,
1078) -> *mut YPendingUpdate {
1079 let txn = txn.as_ref().unwrap();
1080 match txn.store().pending_update() {
1081 None => null_mut(),
1082 Some(u) => {
1083 let binary = u.update.encode_v1().into_boxed_slice();
1084 let update_len = binary.len() as u32;
1085 let missing = YStateVector::new(&u.missing);
1086 let update = YPendingUpdate {
1087 missing,
1088 update_len,
1089 update_v1: Box::into_raw(binary) as *mut c_char,
1090 };
1091 Box::into_raw(Box::new(update))
1092 }
1093 }
1094}
1095
1096#[repr(C)]
1100pub struct YPendingUpdate {
1101 pub missing: YStateVector,
1104 pub update_v1: *mut c_char,
1106 pub update_len: u32,
1108}
1109
1110#[no_mangle]
1111pub unsafe extern "C" fn ypending_update_destroy(update: *mut YPendingUpdate) {
1112 if update.is_null() {
1113 return;
1114 }
1115 let update = Box::from_raw(update);
1116 drop(update.missing);
1117 ybinary_destroy(update.update_v1, update.update_len);
1118}
1119
1120#[no_mangle]
1124pub unsafe extern "C" fn yupdate_debug_v1(update: *const c_char, update_len: u32) -> *mut c_char {
1125 assert!(!update.is_null());
1126
1127 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1128 if let Ok(u) = Update::decode_v1(data) {
1129 let str = format!("{:#?}", u);
1130 CString::new(str).unwrap().into_raw()
1131 } else {
1132 null_mut()
1133 }
1134}
1135
1136#[no_mangle]
1140pub unsafe extern "C" fn yupdate_debug_v2(update: *const c_char, update_len: u32) -> *mut c_char {
1141 assert!(!update.is_null());
1142
1143 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1144 if let Ok(u) = Update::decode_v2(data) {
1145 let str = format!("{:#?}", u);
1146 CString::new(str).unwrap().into_raw()
1147 } else {
1148 null_mut()
1149 }
1150}
1151
1152#[no_mangle]
1166pub unsafe extern "C" fn ytransaction_apply(
1167 txn: *mut Transaction,
1168 diff: *const c_char,
1169 diff_len: u32,
1170) -> u8 {
1171 assert!(!txn.is_null());
1172 assert!(!diff.is_null());
1173
1174 let update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1175 let mut decoder = DecoderV1::from(update);
1176 match Update::decode(&mut decoder) {
1177 Ok(update) => {
1178 let txn = txn.as_mut().unwrap();
1179 let txn = txn
1180 .as_mut()
1181 .expect("provided transaction was not writeable");
1182 match txn.apply_update(update) {
1183 Ok(_) => 0,
1184 Err(e) => update_err_code(e),
1185 }
1186 }
1187 Err(e) => err_code(e),
1188 }
1189}
1190
1191#[no_mangle]
1205pub unsafe extern "C" fn ytransaction_apply_v2(
1206 txn: *mut Transaction,
1207 diff: *const c_char,
1208 diff_len: u32,
1209) -> u8 {
1210 assert!(!txn.is_null());
1211 assert!(!diff.is_null());
1212
1213 let mut update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1214 match Update::decode_v2(&mut update) {
1215 Ok(update) => {
1216 let txn = txn.as_mut().unwrap();
1217 let txn = txn
1218 .as_mut()
1219 .expect("provided transaction was not writeable");
1220 match txn.apply_update(update) {
1221 Ok(_) => 0,
1222 Err(e) => update_err_code(e),
1223 }
1224 }
1225 Err(e) => err_code(e),
1226 }
1227}
1228
1229pub const ERR_CODE_IO: u8 = 1;
1231
1232pub const ERR_CODE_VAR_INT: u8 = 2;
1234
1235pub const ERR_CODE_EOS: u8 = 3;
1237
1238pub const ERR_CODE_UNEXPECTED_VALUE: u8 = 4;
1240
1241pub const ERR_CODE_INVALID_JSON: u8 = 5;
1243
1244pub const ERR_CODE_OTHER: u8 = 6;
1246
1247pub const ERR_NOT_ENOUGH_MEMORY: u8 = 7;
1249
1250pub const ERR_TYPE_MISMATCH: u8 = 8;
1252
1253pub const ERR_CUSTOM: u8 = 9;
1255
1256pub const ERR_INVALID_PARENT: u8 = 9;
1258
1259fn err_code(e: Error) -> u8 {
1260 match e {
1261 Error::InvalidVarInt => ERR_CODE_VAR_INT,
1262 Error::EndOfBuffer(_) => ERR_CODE_EOS,
1263 Error::UnexpectedValue => ERR_CODE_UNEXPECTED_VALUE,
1264 Error::InvalidJSON(_) => ERR_CODE_INVALID_JSON,
1265 Error::NotEnoughMemory(_) => ERR_NOT_ENOUGH_MEMORY,
1266 Error::TypeMismatch(_) => ERR_TYPE_MISMATCH,
1267 Error::Custom(_) => ERR_CUSTOM,
1268 }
1269}
1270fn update_err_code(e: UpdateError) -> u8 {
1271 match e {
1272 UpdateError::InvalidParent(_, _) => ERR_INVALID_PARENT,
1273 }
1274}
1275
1276#[no_mangle]
1278pub unsafe extern "C" fn ytext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
1279 assert!(!txt.is_null());
1280 let txn = txn.as_ref().unwrap();
1281 let txt = TextRef::from_raw_branch(txt);
1282 txt.len(txn)
1283}
1284
1285#[no_mangle]
1289pub unsafe extern "C" fn ytext_string(txt: *const Branch, txn: *const Transaction) -> *mut c_char {
1290 assert!(!txt.is_null());
1291
1292 let txn = txn.as_ref().unwrap();
1293 let txt = TextRef::from_raw_branch(txt);
1294 let str = txt.get_string(txn);
1295 CString::new(str).unwrap().into_raw()
1296}
1297
1298#[no_mangle]
1309pub unsafe extern "C" fn ytext_insert(
1310 txt: *const Branch,
1311 txn: *mut Transaction,
1312 index: u32,
1313 value: *const c_char,
1314 attrs: *const YInput,
1315) {
1316 assert!(!txt.is_null());
1317 assert!(!txn.is_null());
1318 assert!(!value.is_null());
1319
1320 let chunk = CStr::from_ptr(value).to_str().unwrap();
1321 let txn = txn.as_mut().unwrap();
1322 let txn = txn
1323 .as_mut()
1324 .expect("provided transaction was not writeable");
1325 let txt = TextRef::from_raw_branch(txt);
1326 let index = index as u32;
1327 if attrs.is_null() {
1328 txt.insert(txn, index, chunk)
1329 } else {
1330 if let Some(attrs) = map_attrs(attrs.read().into()) {
1331 txt.insert_with_attributes(txn, index, chunk, attrs)
1332 } else {
1333 panic!("ytext_insert: passed attributes are not of map type")
1334 }
1335 }
1336}
1337
1338#[no_mangle]
1341pub unsafe extern "C" fn ytext_format(
1342 txt: *const Branch,
1343 txn: *mut Transaction,
1344 index: u32,
1345 len: u32,
1346 attrs: *const YInput,
1347) {
1348 assert!(!txt.is_null());
1349 assert!(!txn.is_null());
1350 assert!(!attrs.is_null());
1351
1352 if let Some(attrs) = map_attrs(attrs.read().into()) {
1353 let txt = TextRef::from_raw_branch(txt);
1354 let txn = txn.as_mut().unwrap();
1355 let txn = txn
1356 .as_mut()
1357 .expect("provided transaction was not writeable");
1358 let index = index as u32;
1359 let len = len as u32;
1360 txt.format(txn, index, len, attrs);
1361 } else {
1362 panic!("ytext_format: passed attributes are not of map type")
1363 }
1364}
1365
1366#[no_mangle]
1377pub unsafe extern "C" fn ytext_insert_embed(
1378 txt: *const Branch,
1379 txn: *mut Transaction,
1380 index: u32,
1381 content: *const YInput,
1382 attrs: *const YInput,
1383) {
1384 assert!(!txt.is_null());
1385 assert!(!txn.is_null());
1386 assert!(!content.is_null());
1387
1388 let txn = txn.as_mut().unwrap();
1389 let txn = txn
1390 .as_mut()
1391 .expect("provided transaction was not writeable");
1392 let txt = TextRef::from_raw_branch(txt);
1393 let index = index as u32;
1394 let content = content.read();
1395 if attrs.is_null() {
1396 txt.insert_embed(txn, index, content);
1397 } else {
1398 if let Some(attrs) = map_attrs(attrs.read().into()) {
1399 txt.insert_embed_with_attributes(txn, index, content, attrs);
1400 } else {
1401 panic!("ytext_insert_embed: passed attributes are not of map type")
1402 }
1403 }
1404}
1405
1406#[no_mangle]
1420pub unsafe extern "C" fn ytext_insert_delta(
1421 txt: *const Branch,
1422 txn: *mut Transaction,
1423 delta: *mut YDeltaIn,
1424 delta_len: u32,
1425) {
1426 let txt = TextRef::from_raw_branch(txt);
1427 let txn = txn.as_mut().unwrap();
1428 let txn = txn
1429 .as_mut()
1430 .expect("provided transaction was not writeable");
1431 let delta = std::slice::from_raw_parts(delta, delta_len as usize);
1432 let mut insert = Vec::with_capacity(delta.len());
1433 for chunk in delta {
1434 let d = chunk.as_input();
1435 insert.push(d);
1436 }
1437 txt.apply_delta(txn, insert);
1438}
1439
1440#[no_mangle]
1444pub unsafe extern "C" fn ydelta_input_retain(len: u32, attrs: *const YInput) -> YDeltaIn {
1445 YDeltaIn {
1446 tag: Y_EVENT_CHANGE_RETAIN,
1447 len,
1448 attributes: attrs,
1449 insert: null(),
1450 }
1451}
1452
1453#[no_mangle]
1456pub unsafe extern "C" fn ydelta_input_delete(len: u32) -> YDeltaIn {
1457 YDeltaIn {
1458 tag: Y_EVENT_CHANGE_DELETE,
1459 len,
1460 attributes: null(),
1461 insert: null(),
1462 }
1463}
1464
1465#[no_mangle]
1471pub unsafe extern "C" fn ydelta_input_insert(
1472 data: *const YInput,
1473 attrs: *const YInput,
1474) -> YDeltaIn {
1475 YDeltaIn {
1476 tag: Y_EVENT_CHANGE_ADD,
1477 len: 1,
1478 attributes: attrs,
1479 insert: data,
1480 }
1481}
1482
1483fn map_attrs(attrs: Any) -> Option<Attrs> {
1484 if let Any::Map(attrs) = attrs {
1485 let attrs = attrs
1486 .iter()
1487 .map(|(k, v)| (k.as_str().into(), v.clone()))
1488 .collect();
1489 Some(attrs)
1490 } else {
1491 None
1492 }
1493}
1494
1495#[no_mangle]
1504pub unsafe extern "C" fn ytext_remove_range(
1505 txt: *const Branch,
1506 txn: *mut Transaction,
1507 index: u32,
1508 length: u32,
1509) {
1510 assert!(!txt.is_null());
1511 assert!(!txn.is_null());
1512
1513 let txn = txn.as_mut().unwrap();
1514 let txn = txn
1515 .as_mut()
1516 .expect("provided transaction was not writeable");
1517 let txt = TextRef::from_raw_branch(txt);
1518 txt.remove_range(txn, index as u32, length as u32)
1519}
1520
1521#[no_mangle]
1523pub unsafe extern "C" fn yarray_len(array: *const Branch) -> u32 {
1524 assert!(!array.is_null());
1525
1526 let array = array.as_ref().unwrap();
1527 array.len() as u32
1528}
1529
1530#[no_mangle]
1535pub unsafe extern "C" fn yarray_get(
1536 array: *const Branch,
1537 txn: *const Transaction,
1538 index: u32,
1539) -> *mut YOutput {
1540 assert!(!array.is_null());
1541
1542 let array = ArrayRef::from_raw_branch(array);
1543 let txn = txn.as_ref().unwrap();
1544
1545 if let Some(val) = array.get(txn, index as u32) {
1546 Box::into_raw(Box::new(YOutput::from(val)))
1547 } else {
1548 std::ptr::null_mut()
1549 }
1550}
1551
1552#[no_mangle]
1563pub unsafe extern "C" fn yarray_get_json(
1564 array: *const Branch,
1565 txn: *const Transaction,
1566 index: u32,
1567) -> *mut c_char {
1568 assert!(!array.is_null());
1569
1570 let array = ArrayRef::from_raw_branch(array);
1571 let txn = txn.as_ref().unwrap();
1572
1573 if let Some(val) = array.get(txn, index as u32) {
1574 let any = val.to_json(txn);
1575 let json = match serde_json::to_string(&any) {
1576 Ok(json) => json,
1577 Err(_) => return std::ptr::null_mut(),
1578 };
1579 CString::new(json).unwrap().into_raw()
1580 } else {
1581 std::ptr::null_mut()
1582 }
1583}
1584
1585#[no_mangle]
1596pub unsafe extern "C" fn yarray_insert_range(
1597 array: *const Branch,
1598 txn: *mut Transaction,
1599 index: u32,
1600 items: *const YInput,
1601 items_len: u32,
1602) {
1603 assert!(!array.is_null());
1604 assert!(!txn.is_null());
1605 assert!(!items.is_null());
1606
1607 let array = ArrayRef::from_raw_branch(array);
1608 let txn = txn.as_mut().unwrap();
1609 let txn = txn
1610 .as_mut()
1611 .expect("provided transaction was not writeable");
1612
1613 let ptr = items;
1614 let mut i = 0;
1615 let mut j = index as u32;
1616 let len = items_len as isize;
1617 while i < len {
1618 let mut vec: Vec<Any> = Vec::default();
1619
1620 while i < len {
1622 let val = ptr.offset(i).read();
1623 if val.tag <= 0 {
1624 let any = val.into();
1625 vec.push(any);
1626 } else {
1627 break;
1628 }
1629 i += 1;
1630 }
1631
1632 if !vec.is_empty() {
1633 let len = vec.len() as u32;
1634 array.insert_range(txn, j, vec);
1635 j += len;
1636 } else {
1637 let val = ptr.offset(i).read();
1638 array.insert(txn, j, val);
1639 i += 1;
1640 j += 1;
1641 }
1642 }
1643}
1644
1645#[no_mangle]
1649pub unsafe extern "C" fn yarray_remove_range(
1650 array: *const Branch,
1651 txn: *mut Transaction,
1652 index: u32,
1653 len: u32,
1654) {
1655 assert!(!array.is_null());
1656 assert!(!txn.is_null());
1657
1658 let array = ArrayRef::from_raw_branch(array);
1659 let txn = txn.as_mut().unwrap();
1660 let txn = txn
1661 .as_mut()
1662 .expect("provided transaction was not writeable");
1663
1664 array.remove_range(txn, index as u32, len as u32)
1665}
1666
1667#[no_mangle]
1668pub unsafe extern "C" fn yarray_move(
1669 array: *const Branch,
1670 txn: *mut Transaction,
1671 source: u32,
1672 target: u32,
1673) {
1674 assert!(!array.is_null());
1675 assert!(!txn.is_null());
1676
1677 let array = ArrayRef::from_raw_branch(array);
1678 let txn = txn.as_mut().unwrap();
1679 let txn = txn
1680 .as_mut()
1681 .expect("provided transaction was not writeable");
1682
1683 array.move_to(txn, source as u32, target as u32)
1684}
1685
1686#[no_mangle]
1692pub unsafe extern "C" fn yarray_iter(
1693 array: *const Branch,
1694 txn: *mut Transaction,
1695) -> *mut ArrayIter {
1696 assert!(!array.is_null());
1697 assert!(!txn.is_null());
1698
1699 let txn = txn.as_ref().unwrap();
1700 let array = &ArrayRef::from_raw_branch(array) as *const ArrayRef;
1701 Box::into_raw(Box::new(ArrayIter(array.as_ref().unwrap().iter(txn))))
1702}
1703
1704#[no_mangle]
1706pub unsafe extern "C" fn yarray_iter_destroy(iter: *mut ArrayIter) {
1707 if !iter.is_null() {
1708 drop(Box::from_raw(iter))
1709 }
1710}
1711
1712#[no_mangle]
1717pub unsafe extern "C" fn yarray_iter_next(iterator: *mut ArrayIter) -> *mut YOutput {
1718 assert!(!iterator.is_null());
1719
1720 let iter = iterator.as_mut().unwrap();
1721 if let Some(v) = iter.0.next() {
1722 let out = YOutput::from(v);
1723 Box::into_raw(Box::new(out))
1724 } else {
1725 std::ptr::null_mut()
1726 }
1727}
1728
1729#[no_mangle]
1734pub unsafe extern "C" fn ymap_iter(map: *const Branch, txn: *const Transaction) -> *mut MapIter {
1735 assert!(!map.is_null());
1736
1737 let txn = txn.as_ref().unwrap();
1738 let map = &MapRef::from_raw_branch(map) as *const MapRef;
1739 Box::into_raw(Box::new(MapIter(map.as_ref().unwrap().iter(txn))))
1740}
1741
1742#[no_mangle]
1744pub unsafe extern "C" fn ymap_iter_destroy(iter: *mut MapIter) {
1745 if !iter.is_null() {
1746 drop(Box::from_raw(iter))
1747 }
1748}
1749
1750#[no_mangle]
1756pub unsafe extern "C" fn ymap_iter_next(iter: *mut MapIter) -> *mut YMapEntry {
1757 assert!(!iter.is_null());
1758
1759 let iter = iter.as_mut().unwrap();
1760 if let Some((key, value)) = iter.0.next() {
1761 let output = YOutput::from(value);
1762 Box::into_raw(Box::new(YMapEntry::new(key, Box::new(output))))
1763 } else {
1764 std::ptr::null_mut()
1765 }
1766}
1767
1768#[no_mangle]
1770pub unsafe extern "C" fn ymap_len(map: *const Branch, txn: *const Transaction) -> u32 {
1771 assert!(!map.is_null());
1772
1773 let txn = txn.as_ref().unwrap();
1774 let map = MapRef::from_raw_branch(map);
1775
1776 map.len(txn)
1777}
1778
1779#[no_mangle]
1788pub unsafe extern "C" fn ymap_insert(
1789 map: *const Branch,
1790 txn: *mut Transaction,
1791 key: *const c_char,
1792 value: *const YInput,
1793) {
1794 assert!(!map.is_null());
1795 assert!(!txn.is_null());
1796 assert!(!key.is_null());
1797 assert!(!value.is_null());
1798
1799 let cstr = CStr::from_ptr(key);
1800 let key = cstr.to_str().unwrap().to_string();
1801
1802 let map = MapRef::from_raw_branch(map);
1803 let txn = txn.as_mut().unwrap();
1804 let txn = txn
1805 .as_mut()
1806 .expect("provided transaction was not writeable");
1807
1808 map.insert(txn, key, value.read());
1809}
1810
1811#[no_mangle]
1816pub unsafe extern "C" fn ymap_remove(
1817 map: *const Branch,
1818 txn: *mut Transaction,
1819 key: *const c_char,
1820) -> u8 {
1821 assert!(!map.is_null());
1822 assert!(!txn.is_null());
1823 assert!(!key.is_null());
1824
1825 let key = CStr::from_ptr(key).to_str().unwrap();
1826
1827 let map = MapRef::from_raw_branch(map);
1828 let txn = txn.as_mut().unwrap();
1829 let txn = txn
1830 .as_mut()
1831 .expect("provided transaction was not writeable");
1832
1833 if let Some(_) = map.remove(txn, key) {
1834 Y_TRUE
1835 } else {
1836 Y_FALSE
1837 }
1838}
1839
1840#[no_mangle]
1846pub unsafe extern "C" fn ymap_get(
1847 map: *const Branch,
1848 txn: *const Transaction,
1849 key: *const c_char,
1850) -> *mut YOutput {
1851 assert!(!map.is_null());
1852 assert!(!key.is_null());
1853 assert!(!txn.is_null());
1854
1855 let txn = txn.as_ref().unwrap();
1856 let key = CStr::from_ptr(key).to_str().unwrap();
1857
1858 let map = MapRef::from_raw_branch(map);
1859
1860 if let Some(value) = map.get(txn, key) {
1861 let output = YOutput::from(value);
1862 Box::into_raw(Box::new(output))
1863 } else {
1864 std::ptr::null_mut()
1865 }
1866}
1867
1868#[no_mangle]
1877pub unsafe extern "C" fn ymap_get_json(
1878 map: *const Branch,
1879 txn: *const Transaction,
1880 key: *const c_char,
1881) -> *mut c_char {
1882 assert!(!map.is_null());
1883 assert!(!key.is_null());
1884 assert!(!txn.is_null());
1885
1886 let txn = txn.as_ref().unwrap();
1887 let key = CStr::from_ptr(key).to_str().unwrap();
1888
1889 let map = MapRef::from_raw_branch(map);
1890
1891 if let Some(value) = map.get(txn, key) {
1892 let any = value.to_json(txn);
1893 match serde_json::to_string(&any) {
1894 Ok(json) => CString::new(json).unwrap().into_raw(),
1895 Err(_) => std::ptr::null_mut(),
1896 }
1897 } else {
1898 std::ptr::null_mut()
1899 }
1900}
1901
1902#[no_mangle]
1904pub unsafe extern "C" fn ymap_remove_all(map: *const Branch, txn: *mut Transaction) {
1905 assert!(!map.is_null());
1906 assert!(!txn.is_null());
1907
1908 let map = MapRef::from_raw_branch(map);
1909 let txn = txn.as_mut().unwrap();
1910 let txn = txn
1911 .as_mut()
1912 .expect("provided transaction was not writeable");
1913
1914 map.clear(txn);
1915}
1916
1917#[no_mangle]
1923pub unsafe extern "C" fn yxmlelem_tag(xml: *const Branch) -> *mut c_char {
1924 assert!(!xml.is_null());
1925 let xml = XmlElementRef::from_raw_branch(xml);
1926 if let Some(tag) = xml.try_tag() {
1927 CString::new(tag.deref()).unwrap().into_raw()
1928 } else {
1929 null_mut()
1930 }
1931}
1932
1933#[no_mangle]
1939pub unsafe extern "C" fn yxmlelem_string(
1940 xml: *const Branch,
1941 txn: *const Transaction,
1942) -> *mut c_char {
1943 assert!(!xml.is_null());
1944 assert!(!txn.is_null());
1945
1946 let txn = txn.as_ref().unwrap();
1947 let xml = XmlElementRef::from_raw_branch(xml);
1948
1949 let str = xml.get_string(txn);
1950 CString::new(str).unwrap().into_raw()
1951}
1952
1953#[no_mangle]
1959pub unsafe extern "C" fn yxmlelem_insert_attr(
1960 xml: *const Branch,
1961 txn: *mut Transaction,
1962 attr_name: *const c_char,
1963 attr_value: *const YInput,
1964) {
1965 assert!(!xml.is_null());
1966 assert!(!txn.is_null());
1967 assert!(!attr_name.is_null());
1968 assert!(!attr_value.is_null());
1969
1970 let xml = XmlElementRef::from_raw_branch(xml);
1971 let txn = txn.as_mut().unwrap();
1972 let txn = txn
1973 .as_mut()
1974 .expect("provided transaction was not writeable");
1975
1976 let key = CStr::from_ptr(attr_name).to_str().unwrap();
1977
1978 xml.insert_attribute(txn, key, attr_value.read());
1979}
1980
1981#[no_mangle]
1985pub unsafe extern "C" fn yxmlelem_remove_attr(
1986 xml: *const Branch,
1987 txn: *mut Transaction,
1988 attr_name: *const c_char,
1989) {
1990 assert!(!xml.is_null());
1991 assert!(!txn.is_null());
1992 assert!(!attr_name.is_null());
1993
1994 let xml = XmlElementRef::from_raw_branch(xml);
1995 let txn = txn.as_mut().unwrap();
1996 let txn = txn
1997 .as_mut()
1998 .expect("provided transaction was not writeable");
1999
2000 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2001 xml.remove_attribute(txn, &key);
2002}
2003
2004#[no_mangle]
2010pub unsafe extern "C" fn yxmlelem_get_attr(
2011 xml: *const Branch,
2012 txn: *const Transaction,
2013 attr_name: *const c_char,
2014) -> *mut YOutput {
2015 assert!(!xml.is_null());
2016 assert!(!attr_name.is_null());
2017 assert!(!txn.is_null());
2018
2019 let xml = XmlElementRef::from_raw_branch(xml);
2020
2021 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2022 let txn = txn.as_ref().unwrap();
2023 if let Some(value) = xml.get_attribute(txn, key) {
2024 let output = YOutput::from(value);
2025 Box::into_raw(Box::new(output))
2026 } else {
2027 std::ptr::null_mut()
2028 }
2029}
2030
2031#[no_mangle]
2036pub unsafe extern "C" fn yxmlelem_attr_iter(
2037 xml: *const Branch,
2038 txn: *const Transaction,
2039) -> *mut Attributes {
2040 assert!(!xml.is_null());
2041 assert!(!txn.is_null());
2042
2043 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2044 let txn = txn.as_ref().unwrap();
2045 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
2046}
2047
2048#[no_mangle]
2053pub unsafe extern "C" fn yxmltext_attr_iter(
2054 xml: *const Branch,
2055 txn: *const Transaction,
2056) -> *mut Attributes {
2057 assert!(!xml.is_null());
2058 assert!(!txn.is_null());
2059
2060 let xml = &XmlTextRef::from_raw_branch(xml) as *const XmlTextRef;
2061 let txn = txn.as_ref().unwrap();
2062 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
2063}
2064
2065#[no_mangle]
2068pub unsafe extern "C" fn yxmlattr_iter_destroy(iterator: *mut Attributes) {
2069 if !iterator.is_null() {
2070 drop(Box::from_raw(iterator))
2071 }
2072}
2073
2074#[no_mangle]
2080pub unsafe extern "C" fn yxmlattr_iter_next(iterator: *mut Attributes) -> *mut YXmlAttr {
2081 assert!(!iterator.is_null());
2082
2083 let iter = iterator.as_mut().unwrap();
2084
2085 if let Some((name, value)) = iter.0.next() {
2086 Box::into_raw(Box::new(YXmlAttr {
2087 name: CString::new(name).unwrap().into_raw(),
2088 value: Box::into_raw(Box::new(YOutput::from(value))),
2089 }))
2090 } else {
2091 std::ptr::null_mut()
2092 }
2093}
2094
2095#[no_mangle]
2103pub unsafe extern "C" fn yxml_next_sibling(
2104 xml: *const Branch,
2105 txn: *const Transaction,
2106) -> *mut YOutput {
2107 assert!(!xml.is_null());
2108 assert!(!txn.is_null());
2109
2110 let xml = XmlElementRef::from_raw_branch(xml);
2111 let txn = txn.as_ref().unwrap();
2112
2113 let mut siblings = xml.siblings(txn);
2114 if let Some(next) = siblings.next() {
2115 match next {
2116 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2117 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2118 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2119 }
2120 } else {
2121 null_mut()
2122 }
2123}
2124
2125#[no_mangle]
2131pub unsafe extern "C" fn yxml_prev_sibling(
2132 xml: *const Branch,
2133 txn: *const Transaction,
2134) -> *mut YOutput {
2135 assert!(!xml.is_null());
2136 assert!(!txn.is_null());
2137
2138 let xml = XmlElementRef::from_raw_branch(xml);
2139 let txn = txn.as_ref().unwrap();
2140
2141 let mut siblings = xml.siblings(txn);
2142 if let Some(next) = siblings.next_back() {
2143 match next {
2144 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2145 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2146 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2147 }
2148 } else {
2149 null_mut()
2150 }
2151}
2152
2153#[no_mangle]
2156pub unsafe extern "C" fn yxmlelem_parent(xml: *const Branch) -> *mut Branch {
2157 assert!(!xml.is_null());
2158
2159 let xml = XmlElementRef::from_raw_branch(xml);
2160
2161 if let Some(parent) = xml.parent() {
2162 let branch = parent.as_ptr();
2163 branch.deref() as *const Branch as *mut Branch
2164 } else {
2165 std::ptr::null_mut()
2166 }
2167}
2168
2169#[no_mangle]
2172pub unsafe extern "C" fn yxmlelem_child_len(xml: *const Branch, txn: *const Transaction) -> u32 {
2173 assert!(!xml.is_null());
2174 assert!(!txn.is_null());
2175
2176 let txn = txn.as_ref().unwrap();
2177 let xml = XmlElementRef::from_raw_branch(xml);
2178
2179 xml.len(txn) as u32
2180}
2181
2182#[no_mangle]
2187pub unsafe extern "C" fn yxmlelem_first_child(xml: *const Branch) -> *mut YOutput {
2188 assert!(!xml.is_null());
2189
2190 let xml = XmlElementRef::from_raw_branch(xml);
2191
2192 if let Some(value) = xml.first_child() {
2193 match value {
2194 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2195 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2196 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2197 }
2198 } else {
2199 std::ptr::null_mut()
2200 }
2201}
2202
2203#[no_mangle]
2209pub unsafe extern "C" fn yxmlelem_tree_walker(
2210 xml: *const Branch,
2211 txn: *const Transaction,
2212) -> *mut TreeWalker {
2213 assert!(!xml.is_null());
2214 assert!(!txn.is_null());
2215
2216 let txn = txn.as_ref().unwrap();
2217 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2218 Box::into_raw(Box::new(TreeWalker(xml.as_ref().unwrap().successors(txn))))
2219}
2220
2221#[no_mangle]
2223pub unsafe extern "C" fn yxmlelem_tree_walker_destroy(iter: *mut TreeWalker) {
2224 if !iter.is_null() {
2225 drop(Box::from_raw(iter))
2226 }
2227}
2228
2229#[no_mangle]
2234pub unsafe extern "C" fn yxmlelem_tree_walker_next(iterator: *mut TreeWalker) -> *mut YOutput {
2235 assert!(!iterator.is_null());
2236
2237 let iter = iterator.as_mut().unwrap();
2238
2239 if let Some(next) = iter.0.next() {
2240 match next {
2241 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2242 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2243 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2244 }
2245 } else {
2246 std::ptr::null_mut()
2247 }
2248}
2249
2250#[no_mangle]
2259pub unsafe extern "C" fn yxmlelem_insert_elem(
2260 xml: *const Branch,
2261 txn: *mut Transaction,
2262 index: u32,
2263 name: *const c_char,
2264) -> *mut Branch {
2265 assert!(!xml.is_null());
2266 assert!(!txn.is_null());
2267 assert!(!name.is_null());
2268
2269 let xml = XmlElementRef::from_raw_branch(xml);
2270 let txn = txn.as_mut().unwrap();
2271 let txn = txn
2272 .as_mut()
2273 .expect("provided transaction was not writeable");
2274
2275 let name = CStr::from_ptr(name).to_str().unwrap();
2276 xml.insert(txn, index as u32, XmlElementPrelim::empty(name))
2277 .into_raw_branch()
2278}
2279
2280#[no_mangle]
2286pub unsafe extern "C" fn yxmlelem_insert_text(
2287 xml: *const Branch,
2288 txn: *mut Transaction,
2289 index: u32,
2290) -> *mut Branch {
2291 assert!(!xml.is_null());
2292 assert!(!txn.is_null());
2293
2294 let xml = XmlElementRef::from_raw_branch(xml);
2295 let txn = txn.as_mut().unwrap();
2296 let txn = txn
2297 .as_mut()
2298 .expect("provided transaction was not writeable");
2299 xml.insert(txn, index as u32, XmlTextPrelim::new(""))
2300 .into_raw_branch()
2301}
2302
2303#[no_mangle]
2307pub unsafe extern "C" fn yxmlelem_remove_range(
2308 xml: *const Branch,
2309 txn: *mut Transaction,
2310 index: u32,
2311 len: u32,
2312) {
2313 assert!(!xml.is_null());
2314 assert!(!txn.is_null());
2315
2316 let xml = XmlElementRef::from_raw_branch(xml);
2317 let txn = txn.as_mut().unwrap();
2318 let txn = txn
2319 .as_mut()
2320 .expect("provided transaction was not writeable");
2321
2322 xml.remove_range(txn, index as u32, len as u32)
2323}
2324
2325#[no_mangle]
2331pub unsafe extern "C" fn yxmlelem_get(
2332 xml: *const Branch,
2333 txn: *const Transaction,
2334 index: u32,
2335) -> *const YOutput {
2336 assert!(!xml.is_null());
2337 assert!(!txn.is_null());
2338
2339 let xml = XmlElementRef::from_raw_branch(xml);
2340 let txn = txn.as_ref().unwrap();
2341
2342 if let Some(child) = xml.get(txn, index as u32) {
2343 match child {
2344 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2345 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2346 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2347 }
2348 } else {
2349 std::ptr::null()
2350 }
2351}
2352
2353#[no_mangle]
2356pub unsafe extern "C" fn yxmltext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
2357 assert!(!txt.is_null());
2358 assert!(!txn.is_null());
2359
2360 let txn = txn.as_ref().unwrap();
2361 let txt = XmlTextRef::from_raw_branch(txt);
2362
2363 txt.len(txn) as u32
2364}
2365
2366#[no_mangle]
2370pub unsafe extern "C" fn yxmltext_string(
2371 txt: *const Branch,
2372 txn: *const Transaction,
2373) -> *mut c_char {
2374 assert!(!txt.is_null());
2375 assert!(!txn.is_null());
2376
2377 let txn = txn.as_ref().unwrap();
2378 let txt = XmlTextRef::from_raw_branch(txt);
2379
2380 let str = txt.get_string(txn);
2381 CString::new(str).unwrap().into_raw()
2382}
2383
2384#[no_mangle]
2395pub unsafe extern "C" fn yxmltext_insert(
2396 txt: *const Branch,
2397 txn: *mut Transaction,
2398 index: u32,
2399 str: *const c_char,
2400 attrs: *const YInput,
2401) {
2402 assert!(!txt.is_null());
2403 assert!(!txn.is_null());
2404 assert!(!str.is_null());
2405
2406 let txt = XmlTextRef::from_raw_branch(txt);
2407 let txn = txn.as_mut().unwrap();
2408 let txn = txn
2409 .as_mut()
2410 .expect("provided transaction was not writeable");
2411 let chunk = CStr::from_ptr(str).to_str().unwrap();
2412
2413 if attrs.is_null() {
2414 txt.insert(txn, index as u32, chunk)
2415 } else {
2416 if let Some(attrs) = map_attrs(attrs.read().into()) {
2417 txt.insert_with_attributes(txn, index as u32, chunk, attrs)
2418 } else {
2419 panic!("yxmltext_insert: passed attributes are not of map type")
2420 }
2421 }
2422}
2423
2424#[no_mangle]
2435pub unsafe extern "C" fn yxmltext_insert_embed(
2436 txt: *const Branch,
2437 txn: *mut Transaction,
2438 index: u32,
2439 content: *const YInput,
2440 attrs: *const YInput,
2441) {
2442 assert!(!txt.is_null());
2443 assert!(!txn.is_null());
2444 assert!(!content.is_null());
2445
2446 let txn = txn.as_mut().unwrap();
2447 let txn = txn
2448 .as_mut()
2449 .expect("provided transaction was not writeable");
2450 let txt = XmlTextRef::from_raw_branch(txt);
2451 let index = index as u32;
2452 let content = content.read();
2453 if attrs.is_null() {
2454 txt.insert_embed(txn, index, content);
2455 } else {
2456 if let Some(attrs) = map_attrs(attrs.read().into()) {
2457 txt.insert_embed_with_attributes(txn, index, content, attrs);
2458 } else {
2459 panic!("yxmltext_insert_embed: passed attributes are not of map type")
2460 }
2461 }
2462}
2463
2464#[no_mangle]
2467pub unsafe extern "C" fn yxmltext_format(
2468 txt: *const Branch,
2469 txn: *mut Transaction,
2470 index: u32,
2471 len: u32,
2472 attrs: *const YInput,
2473) {
2474 assert!(!txt.is_null());
2475 assert!(!txn.is_null());
2476 assert!(!attrs.is_null());
2477
2478 if let Some(attrs) = map_attrs(attrs.read().into()) {
2479 let txt = XmlTextRef::from_raw_branch(txt);
2480 let txn = txn.as_mut().unwrap();
2481 let txn = txn
2482 .as_mut()
2483 .expect("provided transaction was not writeable");
2484 let index = index as u32;
2485 let len = len as u32;
2486 txt.format(txn, index, len, attrs);
2487 } else {
2488 panic!("yxmltext_format: passed attributes are not of map type")
2489 }
2490}
2491
2492#[no_mangle]
2501pub unsafe extern "C" fn yxmltext_remove_range(
2502 txt: *const Branch,
2503 txn: *mut Transaction,
2504 idx: u32,
2505 len: u32,
2506) {
2507 assert!(!txt.is_null());
2508 assert!(!txn.is_null());
2509
2510 let txt = XmlTextRef::from_raw_branch(txt);
2511 let txn = txn.as_mut().unwrap();
2512 let txn = txn
2513 .as_mut()
2514 .expect("provided transaction was not writeable");
2515 txt.remove_range(txn, idx as u32, len as u32)
2516}
2517
2518#[no_mangle]
2524pub unsafe extern "C" fn yxmltext_insert_attr(
2525 txt: *const Branch,
2526 txn: *mut Transaction,
2527 attr_name: *const c_char,
2528 attr_value: *const YInput,
2529) {
2530 assert!(!txt.is_null());
2531 assert!(!txn.is_null());
2532 assert!(!attr_name.is_null());
2533 assert!(!attr_value.is_null());
2534
2535 let txt = XmlTextRef::from_raw_branch(txt);
2536 let txn = txn.as_mut().unwrap();
2537 let txn = txn
2538 .as_mut()
2539 .expect("provided transaction was not writeable");
2540
2541 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2542
2543 txt.insert_attribute(txn, name, attr_value.read());
2544}
2545
2546#[no_mangle]
2550pub unsafe extern "C" fn yxmltext_remove_attr(
2551 txt: *const Branch,
2552 txn: *mut Transaction,
2553 attr_name: *const c_char,
2554) {
2555 assert!(!txt.is_null());
2556 assert!(!txn.is_null());
2557 assert!(!attr_name.is_null());
2558
2559 let txt = XmlTextRef::from_raw_branch(txt);
2560 let txn = txn.as_mut().unwrap();
2561 let txn = txn
2562 .as_mut()
2563 .expect("provided transaction was not writeable");
2564 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2565
2566 txt.remove_attribute(txn, &name)
2567}
2568
2569#[no_mangle]
2575pub unsafe extern "C" fn yxmltext_get_attr(
2576 txt: *const Branch,
2577 txn: *const Transaction,
2578 attr_name: *const c_char,
2579) -> *mut YOutput {
2580 assert!(!txt.is_null());
2581 assert!(!attr_name.is_null());
2582 assert!(!txn.is_null());
2583
2584 let txn = txn.as_ref().unwrap();
2585 let txt = XmlTextRef::from_raw_branch(txt);
2586 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2587
2588 if let Some(value) = txt.get_attribute(txn, name) {
2589 let output = YOutput::from(value);
2590 Box::into_raw(Box::new(output))
2591 } else {
2592 std::ptr::null_mut()
2593 }
2594}
2595
2596#[no_mangle]
2602pub unsafe extern "C" fn ytext_chunks(
2603 txt: *const Branch,
2604 txn: *const Transaction,
2605 chunks_len: *mut u32,
2606) -> *mut YChunk {
2607 assert!(!txt.is_null());
2608 assert!(!txn.is_null());
2609
2610 let txt = TextRef::from_raw_branch(txt);
2611 let txn = txn.as_ref().unwrap();
2612
2613 let diffs = txt.diff(txn, YChange::identity);
2614 let chunks: Vec<_> = diffs.into_iter().map(YChunk::from).collect();
2615 let out = chunks.into_boxed_slice();
2616 *chunks_len = out.len() as u32;
2617 Box::into_raw(out) as *mut _
2618}
2619
2620#[no_mangle]
2622pub unsafe extern "C" fn ychunks_destroy(chunks: *mut YChunk, len: u32) {
2623 drop(Vec::from_raw_parts(chunks, len as usize, len as usize));
2624}
2625
2626pub const YCHANGE_ADD: i8 = 1;
2627pub const YCHANGE_RETAIN: i8 = 0;
2628pub const YCHANGE_REMOVE: i8 = -1;
2629
2630#[repr(C)]
2632pub struct YChunk {
2633 pub data: YOutput,
2636 pub fmt_len: u32,
2638 pub fmt: *mut YMapEntry,
2640}
2641
2642impl From<Diff<YChange>> for YChunk {
2643 fn from(diff: Diff<YChange>) -> Self {
2644 let data = YOutput::from(diff.insert);
2645 let mut fmt_len = 0;
2646 let fmt = if let Some(attrs) = diff.attributes {
2647 fmt_len = attrs.len() as u32;
2648 let mut fmt = Vec::with_capacity(attrs.len());
2649 for (k, v) in attrs.into_iter() {
2650 let output = YOutput::from(&v); let e = YMapEntry::new(k.as_ref(), Box::new(output));
2652 fmt.push(e);
2653 }
2654 Box::into_raw(fmt.into_boxed_slice()) as *mut _
2655 } else {
2656 null_mut()
2657 };
2658 YChunk { data, fmt_len, fmt }
2659 }
2660}
2661
2662impl Drop for YChunk {
2663 fn drop(&mut self) {
2664 if !self.fmt.is_null() {
2665 drop(unsafe {
2666 Vec::from_raw_parts(self.fmt, self.fmt_len as usize, self.fmt_len as usize)
2667 });
2668 }
2669 }
2670}
2671
2672#[repr(C)]
2679pub struct YInput {
2680 pub tag: i8,
2697
2698 pub len: u32,
2707
2708 value: YInputContent,
2710}
2711
2712impl YInput {
2713 fn into(self) -> Any {
2714 let tag = self.tag;
2715 unsafe {
2716 match tag {
2717 Y_JSON_STR => {
2718 let str = CStr::from_ptr(self.value.str).to_str().unwrap().into();
2719 Any::String(str)
2720 }
2721 Y_JSON => {
2722 let json_str = CStr::from_ptr(self.value.str).to_str().unwrap();
2723 serde_json::from_str(json_str).unwrap()
2724 }
2725 Y_JSON_NULL => Any::Null,
2726 Y_JSON_UNDEF => Any::Undefined,
2727 Y_JSON_INT => Any::BigInt(self.value.integer),
2728 Y_JSON_NUM => Any::Number(self.value.num),
2729 Y_JSON_BOOL => Any::Bool(if self.value.flag == 0 { false } else { true }),
2730 Y_JSON_BUF => Any::from(std::slice::from_raw_parts(
2731 self.value.buf as *mut u8,
2732 self.len as usize,
2733 )),
2734 Y_JSON_ARR => {
2735 let ptr = self.value.values;
2736 let mut dst: Vec<Any> = Vec::with_capacity(self.len as usize);
2737 let mut i = 0;
2738 while i < self.len as isize {
2739 let value = ptr.offset(i).read();
2740 let any = value.into();
2741 dst.push(any);
2742 i += 1;
2743 }
2744 Any::from(dst)
2745 }
2746 Y_JSON_MAP => {
2747 let mut dst = HashMap::with_capacity(self.len as usize);
2748 let keys = self.value.map.keys;
2749 let values = self.value.map.values;
2750 let mut i = 0;
2751 while i < self.len as isize {
2752 let key = CStr::from_ptr(keys.offset(i).read())
2753 .to_str()
2754 .unwrap()
2755 .to_owned();
2756 let value = values.offset(i).read().into();
2757 dst.insert(key, value);
2758 i += 1;
2759 }
2760 Any::from(dst)
2761 }
2762 Y_DOC => Any::Undefined,
2763 other => panic!("Cannot convert input - unknown tag: {}", other),
2764 }
2765 }
2766 }
2767}
2768
2769impl Into<EmbedPrelim<YInput>> for YInput {
2770 fn into(self) -> EmbedPrelim<YInput> {
2771 if self.tag <= 0 {
2772 EmbedPrelim::Primitive(self.into())
2773 } else {
2774 EmbedPrelim::Shared(self)
2775 }
2776 }
2777}
2778
2779#[repr(C)]
2780union YInputContent {
2781 flag: u8,
2782 num: f64,
2783 integer: i64,
2784 str: *mut c_char,
2785 buf: *mut c_char,
2786 values: *mut YInput,
2787 map: ManuallyDrop<YMapInputData>,
2788 doc: *mut Doc,
2789 weak: *const Weak,
2790}
2791
2792#[repr(C)]
2793struct YMapInputData {
2794 keys: *mut *mut c_char,
2795 values: *mut YInput,
2796}
2797
2798impl Drop for YInput {
2799 fn drop(&mut self) {}
2800}
2801
2802impl Prelim for YInput {
2803 type Return = Unused;
2804
2805 fn into_content<'doc>(self, _: &mut yrs::TransactionMut<'doc>) -> (ItemContent, Option<Self>) {
2806 unsafe {
2807 if self.tag <= 0 {
2808 (ItemContent::Any(vec![self.into()]), None)
2809 } else if self.tag == Y_DOC {
2810 let doc = self.value.doc.as_ref().unwrap();
2811 (ItemContent::Doc(None, doc.clone()), None)
2812 } else {
2813 let type_ref = match self.tag {
2814 Y_MAP => TypeRef::Map,
2815 Y_ARRAY => TypeRef::Array,
2816 Y_TEXT => TypeRef::Text,
2817 Y_XML_TEXT => TypeRef::XmlText,
2818 Y_XML_ELEM => {
2819 let name: Arc<str> =
2820 CStr::from_ptr(self.value.str).to_str().unwrap().into();
2821 TypeRef::XmlElement(name)
2822 }
2823 Y_WEAK_LINK => {
2824 let source = Arc::from_raw(self.value.weak);
2825 TypeRef::WeakLink(source)
2826 }
2827 Y_XML_FRAG => TypeRef::XmlFragment,
2828 other => panic!("unrecognized YInput tag: {}", other),
2829 };
2830 let inner = Branch::new(type_ref);
2831 (ItemContent::Type(inner), Some(self))
2832 }
2833 }
2834 }
2835
2836 fn integrate(self, txn: &mut yrs::TransactionMut, inner_ref: BranchPtr) {
2837 unsafe {
2838 match self.tag {
2839 Y_MAP => {
2840 let map = MapRef::from(inner_ref);
2841 let keys = self.value.map.keys;
2842 let values = self.value.map.values;
2843 let mut i = 0;
2844 while i < self.len as isize {
2845 let key = CStr::from_ptr(keys.offset(i).read())
2846 .to_str()
2847 .unwrap()
2848 .to_owned();
2849 let value = values.offset(i).read();
2850 map.insert(txn, key, value);
2851 i += 1;
2852 }
2853 }
2854 Y_ARRAY => {
2855 let array = ArrayRef::from(inner_ref);
2856 let ptr = self.value.values;
2857 let len = self.len as isize;
2858 let mut i = 0;
2859 while i < len {
2860 let value = ptr.offset(i).read();
2861 array.push_back(txn, value);
2862 i += 1;
2863 }
2864 }
2865 Y_TEXT => {
2866 let text = TextRef::from(inner_ref);
2867 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2868 text.push(txn, init);
2869 }
2870 Y_XML_TEXT => {
2871 let text = XmlTextRef::from(inner_ref);
2872 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2873 text.push(txn, init);
2874 }
2875 _ => { }
2876 }
2877 }
2878 }
2879}
2880
2881#[repr(C)]
2887pub struct YOutput {
2888 pub tag: i8,
2906
2907 pub len: u32,
2915
2916 value: YOutputContent,
2918}
2919
2920impl YOutput {
2921 #[inline]
2922 unsafe fn null() -> YOutput {
2923 YOutput {
2924 tag: Y_JSON_NULL,
2925 len: 0,
2926 value: MaybeUninit::uninit().assume_init(),
2927 }
2928 }
2929
2930 #[inline]
2931 unsafe fn undefined() -> YOutput {
2932 YOutput {
2933 tag: Y_JSON_UNDEF,
2934 len: 0,
2935 value: MaybeUninit::uninit().assume_init(),
2936 }
2937 }
2938}
2939
2940impl std::fmt::Display for YOutput {
2941 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2942 let tag = self.tag;
2943 unsafe {
2944 if tag == Y_JSON_INT {
2945 write!(f, "{}", self.value.integer)
2946 } else if tag == Y_JSON_NUM {
2947 write!(f, "{}", self.value.num)
2948 } else if tag == Y_JSON_BOOL {
2949 write!(
2950 f,
2951 "{}",
2952 if self.value.flag == 0 {
2953 "false"
2954 } else {
2955 "true"
2956 }
2957 )
2958 } else if tag == Y_JSON_UNDEF {
2959 write!(f, "undefined")
2960 } else if tag == Y_JSON_NULL {
2961 write!(f, "null")
2962 } else if tag == Y_JSON_STR {
2963 write!(f, "{}", CString::from_raw(self.value.str).to_str().unwrap())
2964 } else if tag == Y_MAP {
2965 write!(f, "YMap")
2966 } else if tag == Y_ARRAY {
2967 write!(f, "YArray")
2968 } else if tag == Y_JSON_ARR {
2969 write!(f, "[")?;
2970 let slice = std::slice::from_raw_parts(self.value.array, self.len as usize);
2971 for o in slice {
2972 write!(f, ", {}", o)?;
2973 }
2974 write!(f, "]")
2975 } else if tag == Y_JSON_MAP {
2976 write!(f, "{{")?;
2977 let slice = std::slice::from_raw_parts(self.value.map, self.len as usize);
2978 for e in slice {
2979 let key = CStr::from_ptr(e.key).to_str().unwrap();
2980 let value = e.value.as_ref().unwrap();
2981 write!(f, ", '{}' => {}", key, value)?;
2982 }
2983 write!(f, "}}")
2984 } else if tag == Y_TEXT {
2985 write!(f, "YText")
2986 } else if tag == Y_XML_TEXT {
2987 write!(f, "YXmlText")
2988 } else if tag == Y_XML_ELEM {
2989 write!(f, "YXmlElement",)
2990 } else if tag == Y_JSON_BUF {
2991 write!(f, "YBinary(len: {})", self.len)
2992 } else {
2993 Ok(())
2994 }
2995 }
2996 }
2997}
2998
2999impl Drop for YOutput {
3000 fn drop(&mut self) {
3001 let tag = self.tag;
3002 unsafe {
3003 match tag {
3004 Y_JSON_STR => drop(CString::from_raw(self.value.str)),
3005 Y_JSON_ARR => drop(Vec::from_raw_parts(
3006 self.value.array,
3007 self.len as usize,
3008 self.len as usize,
3009 )),
3010 Y_JSON_MAP => drop(Vec::from_raw_parts(
3011 self.value.map,
3012 self.len as usize,
3013 self.len as usize,
3014 )),
3015 Y_JSON_BUF => drop(Vec::from_raw_parts(
3016 self.value.buf as *mut u8,
3018 self.len as usize,
3019 self.len as usize,
3020 )),
3021 Y_DOC => drop(Box::from_raw(self.value.y_doc)),
3022 _ => { }
3023 }
3024 }
3025 }
3026}
3027
3028impl From<Out> for YOutput {
3029 fn from(v: Out) -> Self {
3030 match v {
3031 Out::Any(v) => Self::from(v),
3032 Out::YText(v) => Self::from(v),
3033 Out::YArray(v) => Self::from(v),
3034 Out::YMap(v) => Self::from(v),
3035 Out::YXmlElement(v) => Self::from(v),
3036 Out::YXmlFragment(v) => Self::from(v),
3037 Out::YXmlText(v) => Self::from(v),
3038 Out::YDoc(v) => Self::from(v),
3039 Out::YWeakLink(v) => Self::from(v),
3040 Out::UndefinedRef(v) => Self::from(v),
3041 }
3042 }
3043}
3044
3045impl From<bool> for YOutput {
3046 #[inline]
3047 fn from(value: bool) -> Self {
3048 YOutput {
3049 tag: Y_JSON_BOOL,
3050 len: 1,
3051 value: YOutputContent {
3052 flag: if value { Y_TRUE } else { Y_FALSE },
3053 },
3054 }
3055 }
3056}
3057
3058impl From<f64> for YOutput {
3059 #[inline]
3060 fn from(value: f64) -> Self {
3061 YOutput {
3062 tag: Y_JSON_NUM,
3063 len: 1,
3064 value: YOutputContent { num: value },
3065 }
3066 }
3067}
3068
3069impl From<i64> for YOutput {
3070 #[inline]
3071 fn from(value: i64) -> Self {
3072 YOutput {
3073 tag: Y_JSON_INT,
3074 len: 1,
3075 value: YOutputContent { integer: value },
3076 }
3077 }
3078}
3079
3080impl<'a> From<&'a str> for YOutput {
3081 fn from(value: &'a str) -> Self {
3082 YOutput {
3083 tag: Y_JSON_STR,
3084 len: value.len() as u32,
3085 value: YOutputContent {
3086 str: CString::new(value).unwrap().into_raw(),
3087 },
3088 }
3089 }
3090}
3091
3092impl<'a> From<&'a [u8]> for YOutput {
3093 fn from(value: &'a [u8]) -> Self {
3094 let value: Box<[u8]> = value.into();
3095 YOutput {
3096 tag: Y_JSON_BUF,
3097 len: value.len() as u32,
3098 value: YOutputContent {
3099 buf: Box::into_raw(value) as *const u8 as *mut c_char,
3100 },
3101 }
3102 }
3103}
3104
3105impl<'a> From<&'a [Any]> for YOutput {
3106 fn from(values: &'a [Any]) -> Self {
3107 let len = values.len() as u32;
3108 let mut array = Vec::with_capacity(values.len());
3109 for v in values.iter() {
3110 let output = YOutput::from(v);
3111 array.push(output);
3112 }
3113 let ptr = array.as_mut_ptr();
3114 forget(array);
3115 YOutput {
3116 tag: Y_JSON_ARR,
3117 len,
3118 value: YOutputContent { array: ptr },
3119 }
3120 }
3121}
3122
3123impl<'a> From<&'a HashMap<String, Any>> for YOutput {
3124 fn from(value: &'a HashMap<String, Any>) -> Self {
3125 let len = value.len() as u32;
3126 let mut array = Vec::with_capacity(len as usize);
3127 for (k, v) in value.iter() {
3128 let entry = YMapEntry::new(k.as_str(), Box::new(YOutput::from(v)));
3129 array.push(entry);
3130 }
3131 let ptr = array.as_mut_ptr();
3132 forget(array);
3133 YOutput {
3134 tag: Y_JSON_MAP,
3135 len,
3136 value: YOutputContent { map: ptr },
3137 }
3138 }
3139}
3140
3141impl<'a> From<&'a Any> for YOutput {
3142 fn from(v: &'a Any) -> Self {
3143 unsafe {
3144 match v {
3145 Any::Null => YOutput::null(),
3146 Any::Undefined => YOutput::undefined(),
3147 Any::Bool(v) => YOutput::from(*v),
3148 Any::Number(v) => YOutput::from(*v),
3149 Any::BigInt(v) => YOutput::from(*v),
3150 Any::String(v) => YOutput::from(v.as_ref()),
3151 Any::Buffer(v) => YOutput::from(v.as_ref()),
3152 Any::Array(v) => YOutput::from(v.as_ref()),
3153 Any::Map(v) => YOutput::from(v.as_ref()),
3154 }
3155 }
3156 }
3157}
3158
3159impl From<Any> for YOutput {
3160 fn from(v: Any) -> Self {
3161 unsafe {
3162 match v {
3163 Any::Null => YOutput::null(),
3164 Any::Undefined => YOutput::undefined(),
3165 Any::Bool(v) => YOutput::from(v),
3166 Any::Number(v) => YOutput::from(v),
3167 Any::BigInt(v) => YOutput::from(v),
3168 Any::String(v) => YOutput::from(v.as_ref()),
3169 Any::Buffer(v) => YOutput::from(v.as_ref()),
3170 Any::Array(v) => YOutput::from(v.as_ref()),
3171 Any::Map(v) => YOutput::from(v.as_ref()),
3172 }
3173 }
3174 }
3175}
3176
3177impl From<TextRef> for YOutput {
3178 fn from(v: TextRef) -> Self {
3179 YOutput {
3180 tag: Y_TEXT,
3181 len: 1,
3182 value: YOutputContent {
3183 y_type: v.into_raw_branch(),
3184 },
3185 }
3186 }
3187}
3188
3189impl From<ArrayRef> for YOutput {
3190 fn from(v: ArrayRef) -> Self {
3191 YOutput {
3192 tag: Y_ARRAY,
3193 len: 1,
3194 value: YOutputContent {
3195 y_type: v.into_raw_branch(),
3196 },
3197 }
3198 }
3199}
3200
3201impl From<WeakRef<BranchPtr>> for YOutput {
3202 fn from(v: WeakRef<BranchPtr>) -> Self {
3203 YOutput {
3204 tag: Y_WEAK_LINK,
3205 len: 1,
3206 value: YOutputContent {
3207 y_type: v.into_raw_branch(),
3208 },
3209 }
3210 }
3211}
3212
3213impl From<MapRef> for YOutput {
3214 fn from(v: MapRef) -> Self {
3215 YOutput {
3216 tag: Y_MAP,
3217 len: 1,
3218 value: YOutputContent {
3219 y_type: v.into_raw_branch(),
3220 },
3221 }
3222 }
3223}
3224
3225impl From<BranchPtr> for YOutput {
3226 fn from(v: BranchPtr) -> Self {
3227 let branch_ref = v.as_ref();
3228 YOutput {
3229 tag: Y_UNDEFINED,
3230 len: 1,
3231 value: YOutputContent {
3232 y_type: branch_ref as *const Branch as *mut Branch,
3233 },
3234 }
3235 }
3236}
3237
3238impl From<XmlElementRef> for YOutput {
3239 fn from(v: XmlElementRef) -> Self {
3240 YOutput {
3241 tag: Y_XML_ELEM,
3242 len: 1,
3243 value: YOutputContent {
3244 y_type: v.into_raw_branch(),
3245 },
3246 }
3247 }
3248}
3249
3250impl From<XmlTextRef> for YOutput {
3251 fn from(v: XmlTextRef) -> Self {
3252 YOutput {
3253 tag: Y_XML_TEXT,
3254 len: 1,
3255 value: YOutputContent {
3256 y_type: v.into_raw_branch(),
3257 },
3258 }
3259 }
3260}
3261
3262impl From<XmlFragmentRef> for YOutput {
3263 fn from(v: XmlFragmentRef) -> Self {
3264 YOutput {
3265 tag: Y_XML_FRAG,
3266 len: 1,
3267 value: YOutputContent {
3268 y_type: v.into_raw_branch(),
3269 },
3270 }
3271 }
3272}
3273
3274impl From<Doc> for YOutput {
3275 fn from(v: Doc) -> Self {
3276 YOutput {
3277 tag: Y_DOC,
3278 len: 1,
3279 value: YOutputContent {
3280 y_doc: Box::into_raw(Box::new(v.clone())),
3281 },
3282 }
3283 }
3284}
3285
3286#[repr(C)]
3287union YOutputContent {
3288 flag: u8,
3289 num: f64,
3290 integer: i64,
3291 str: *mut c_char,
3292 buf: *const c_char,
3293 array: *mut YOutput,
3294 map: *mut YMapEntry,
3295 y_type: *mut Branch,
3296 y_doc: *mut Doc,
3297}
3298
3299#[no_mangle]
3301pub unsafe extern "C" fn youtput_destroy(val: *mut YOutput) {
3302 if !val.is_null() {
3303 drop(Box::from_raw(val))
3304 }
3305}
3306
3307#[no_mangle]
3310pub unsafe extern "C" fn yinput_null() -> YInput {
3311 YInput {
3312 tag: Y_JSON_NULL,
3313 len: 0,
3314 value: MaybeUninit::uninit().assume_init(),
3315 }
3316}
3317
3318#[no_mangle]
3321pub unsafe extern "C" fn yinput_undefined() -> YInput {
3322 YInput {
3323 tag: Y_JSON_UNDEF,
3324 len: 0,
3325 value: MaybeUninit::uninit().assume_init(),
3326 }
3327}
3328
3329#[no_mangle]
3332pub unsafe extern "C" fn yinput_bool(flag: u8) -> YInput {
3333 YInput {
3334 tag: Y_JSON_BOOL,
3335 len: 1,
3336 value: YInputContent { flag },
3337 }
3338}
3339
3340#[no_mangle]
3343pub unsafe extern "C" fn yinput_float(num: f64) -> YInput {
3344 YInput {
3345 tag: Y_JSON_NUM,
3346 len: 1,
3347 value: YInputContent { num },
3348 }
3349}
3350
3351#[no_mangle]
3354pub unsafe extern "C" fn yinput_long(integer: i64) -> YInput {
3355 YInput {
3356 tag: Y_JSON_INT,
3357 len: 1,
3358 value: YInputContent { integer },
3359 }
3360}
3361
3362#[no_mangle]
3367pub unsafe extern "C" fn yinput_string(str: *const c_char) -> YInput {
3368 YInput {
3369 tag: Y_JSON_STR,
3370 len: 1,
3371 value: YInputContent {
3372 str: str as *mut c_char,
3373 },
3374 }
3375}
3376
3377#[no_mangle]
3383pub unsafe extern "C" fn yinput_json(str: *const c_char) -> YInput {
3384 YInput {
3385 tag: Y_JSON,
3386 len: 1,
3387 value: YInputContent {
3388 str: str as *mut c_char,
3389 },
3390 }
3391}
3392
3393#[no_mangle]
3397pub unsafe extern "C" fn yinput_binary(buf: *const c_char, len: u32) -> YInput {
3398 YInput {
3399 tag: Y_JSON_BUF,
3400 len,
3401 value: YInputContent {
3402 buf: buf as *mut c_char,
3403 },
3404 }
3405}
3406
3407#[no_mangle]
3411pub unsafe extern "C" fn yinput_json_array(values: *mut YInput, len: u32) -> YInput {
3412 YInput {
3413 tag: Y_JSON_ARR,
3414 len,
3415 value: YInputContent { values },
3416 }
3417}
3418
3419#[no_mangle]
3426pub unsafe extern "C" fn yinput_json_map(
3427 keys: *mut *mut c_char,
3428 values: *mut YInput,
3429 len: u32,
3430) -> YInput {
3431 YInput {
3432 tag: Y_JSON_MAP,
3433 len,
3434 value: YInputContent {
3435 map: ManuallyDrop::new(YMapInputData { keys, values }),
3436 },
3437 }
3438}
3439
3440#[no_mangle]
3445pub unsafe extern "C" fn yinput_yarray(values: *mut YInput, len: u32) -> YInput {
3446 YInput {
3447 tag: Y_ARRAY,
3448 len,
3449 value: YInputContent { values },
3450 }
3451}
3452
3453#[no_mangle]
3460pub unsafe extern "C" fn yinput_ymap(
3461 keys: *mut *mut c_char,
3462 values: *mut YInput,
3463 len: u32,
3464) -> YInput {
3465 YInput {
3466 tag: Y_MAP,
3467 len,
3468 value: YInputContent {
3469 map: ManuallyDrop::new(YMapInputData { keys, values }),
3470 },
3471 }
3472}
3473
3474#[no_mangle]
3480pub unsafe extern "C" fn yinput_ytext(str: *mut c_char) -> YInput {
3481 YInput {
3482 tag: Y_TEXT,
3483 len: 1,
3484 value: YInputContent { str },
3485 }
3486}
3487
3488#[no_mangle]
3494pub unsafe extern "C" fn yinput_yxmlelem(name: *mut c_char) -> YInput {
3495 YInput {
3496 tag: Y_XML_ELEM,
3497 len: 1,
3498 value: YInputContent { str: name },
3499 }
3500}
3501
3502#[no_mangle]
3508pub unsafe extern "C" fn yinput_yxmltext(str: *mut c_char) -> YInput {
3509 YInput {
3510 tag: Y_XML_TEXT,
3511 len: 1,
3512 value: YInputContent { str },
3513 }
3514}
3515
3516#[no_mangle]
3521pub unsafe extern "C" fn yinput_ydoc(doc: *mut Doc) -> YInput {
3522 YInput {
3523 tag: Y_DOC,
3524 len: 1,
3525 value: YInputContent { doc },
3526 }
3527}
3528
3529#[no_mangle]
3532pub unsafe extern "C" fn yinput_weak(weak: *const Weak) -> YInput {
3533 YInput {
3534 tag: Y_WEAK_LINK,
3535 len: 1,
3536 value: YInputContent { weak },
3537 }
3538}
3539
3540#[no_mangle]
3543pub unsafe extern "C" fn youtput_read_ydoc(val: *const YOutput) -> *mut Doc {
3544 let v = val.as_ref().unwrap();
3545 if v.tag == Y_DOC {
3546 v.value.y_doc
3547 } else {
3548 std::ptr::null_mut()
3549 }
3550}
3551
3552#[no_mangle]
3556pub unsafe extern "C" fn youtput_read_bool(val: *const YOutput) -> *const u8 {
3557 let v = val.as_ref().unwrap();
3558 if v.tag == Y_JSON_BOOL {
3559 &v.value.flag
3560 } else {
3561 std::ptr::null()
3562 }
3563}
3564
3565#[no_mangle]
3570pub unsafe extern "C" fn youtput_read_float(val: *const YOutput) -> *const f64 {
3571 let v = val.as_ref().unwrap();
3572 if v.tag == Y_JSON_NUM {
3573 &v.value.num
3574 } else {
3575 std::ptr::null()
3576 }
3577}
3578
3579#[no_mangle]
3584pub unsafe extern "C" fn youtput_read_long(val: *const YOutput) -> *const i64 {
3585 let v = val.as_ref().unwrap();
3586 if v.tag == Y_JSON_INT {
3587 &v.value.integer
3588 } else {
3589 std::ptr::null()
3590 }
3591}
3592
3593#[no_mangle]
3600pub unsafe extern "C" fn youtput_read_string(val: *const YOutput) -> *mut c_char {
3601 let v = val.as_ref().unwrap();
3602 if v.tag == Y_JSON_STR {
3603 v.value.str
3604 } else {
3605 std::ptr::null_mut()
3606 }
3607}
3608
3609#[no_mangle]
3616pub unsafe extern "C" fn youtput_read_binary(val: *const YOutput) -> *const c_char {
3617 let v = val.as_ref().unwrap();
3618 if v.tag == Y_JSON_BUF {
3619 v.value.buf
3620 } else {
3621 std::ptr::null()
3622 }
3623}
3624
3625#[no_mangle]
3632pub unsafe extern "C" fn youtput_read_json_array(val: *const YOutput) -> *mut YOutput {
3633 let v = val.as_ref().unwrap();
3634 if v.tag == Y_JSON_ARR {
3635 v.value.array
3636 } else {
3637 std::ptr::null_mut()
3638 }
3639}
3640
3641#[no_mangle]
3648pub unsafe extern "C" fn youtput_read_json_map(val: *const YOutput) -> *mut YMapEntry {
3649 let v = val.as_ref().unwrap();
3650 if v.tag == Y_JSON_MAP {
3651 v.value.map
3652 } else {
3653 std::ptr::null_mut()
3654 }
3655}
3656
3657#[no_mangle]
3663pub unsafe extern "C" fn youtput_read_yarray(val: *const YOutput) -> *mut Branch {
3664 let v = val.as_ref().unwrap();
3665 if v.tag == Y_ARRAY {
3666 v.value.y_type
3667 } else {
3668 std::ptr::null_mut()
3669 }
3670}
3671
3672#[no_mangle]
3678pub unsafe extern "C" fn youtput_read_yxmlelem(val: *const YOutput) -> *mut Branch {
3679 let v = val.as_ref().unwrap();
3680 if v.tag == Y_XML_ELEM {
3681 v.value.y_type
3682 } else {
3683 std::ptr::null_mut()
3684 }
3685}
3686
3687#[no_mangle]
3693pub unsafe extern "C" fn youtput_read_ymap(val: *const YOutput) -> *mut Branch {
3694 let v = val.as_ref().unwrap();
3695 if v.tag == Y_MAP {
3696 v.value.y_type
3697 } else {
3698 std::ptr::null_mut()
3699 }
3700}
3701
3702#[no_mangle]
3708pub unsafe extern "C" fn youtput_read_ytext(val: *const YOutput) -> *mut Branch {
3709 let v = val.as_ref().unwrap();
3710 if v.tag == Y_TEXT {
3711 v.value.y_type
3712 } else {
3713 std::ptr::null_mut()
3714 }
3715}
3716
3717#[no_mangle]
3723pub unsafe extern "C" fn youtput_read_yxmltext(val: *const YOutput) -> *mut Branch {
3724 let v = val.as_ref().unwrap();
3725 if v.tag == Y_XML_TEXT {
3726 v.value.y_type
3727 } else {
3728 std::ptr::null_mut()
3729 }
3730}
3731
3732#[no_mangle]
3738pub unsafe extern "C" fn youtput_read_yweak(val: *const YOutput) -> *mut Branch {
3739 let v = val.as_ref().unwrap();
3740 if v.tag == Y_WEAK_LINK {
3741 v.value.y_type
3742 } else {
3743 std::ptr::null_mut()
3744 }
3745}
3746
3747#[no_mangle]
3749pub unsafe extern "C" fn yunobserve(subscription: *mut Subscription) {
3750 drop(unsafe { Box::from_raw(subscription) })
3751}
3752
3753#[no_mangle]
3758pub unsafe extern "C" fn ytext_observe(
3759 txt: *const Branch,
3760 state: *mut c_void,
3761 cb: extern "C" fn(*mut c_void, *const YTextEvent),
3762) -> *mut Subscription {
3763 assert!(!txt.is_null());
3764 let state = CallbackState::new(state);
3765
3766 let txt = TextRef::from_raw_branch(txt);
3767 let subscription = txt.observe(move |txn, e| {
3768 let e = YTextEvent::new(e, txn);
3769 cb(state.0, &e as *const YTextEvent);
3770 });
3771 Box::into_raw(Box::new(subscription))
3772}
3773
3774#[no_mangle]
3779pub unsafe extern "C" fn ymap_observe(
3780 map: *const Branch,
3781 state: *mut c_void,
3782 cb: extern "C" fn(*mut c_void, *const YMapEvent),
3783) -> *mut Subscription {
3784 assert!(!map.is_null());
3785 let state = CallbackState::new(state);
3786
3787 let map = MapRef::from_raw_branch(map);
3788 let subscription = map.observe(move |txn, e| {
3789 let e = YMapEvent::new(e, txn);
3790 cb(state.0, &e as *const YMapEvent);
3791 });
3792 Box::into_raw(Box::new(subscription))
3793}
3794
3795#[no_mangle]
3800pub unsafe extern "C" fn yarray_observe(
3801 array: *const Branch,
3802 state: *mut c_void,
3803 cb: extern "C" fn(*mut c_void, *const YArrayEvent),
3804) -> *mut Subscription {
3805 assert!(!array.is_null());
3806 let state = CallbackState::new(state);
3807
3808 let array = ArrayRef::from_raw_branch(array);
3809 let subscription = array.observe(move |txn, e| {
3810 let e = YArrayEvent::new(e, txn);
3811 cb(state.0, &e as *const YArrayEvent);
3812 });
3813 Box::into_raw(Box::new(subscription))
3814}
3815
3816#[no_mangle]
3821pub unsafe extern "C" fn yxmlelem_observe(
3822 xml: *const Branch,
3823 state: *mut c_void,
3824 cb: extern "C" fn(*mut c_void, *const YXmlEvent),
3825) -> *mut Subscription {
3826 assert!(!xml.is_null());
3827 let state = CallbackState::new(state);
3828
3829 let xml = XmlElementRef::from_raw_branch(xml);
3830 let subscription = xml.observe(move |txn, e| {
3831 let e = YXmlEvent::new(e, txn);
3832 cb(state.0, &e as *const YXmlEvent);
3833 });
3834 Box::into_raw(Box::new(subscription))
3835}
3836
3837#[no_mangle]
3842pub unsafe extern "C" fn yxmltext_observe(
3843 xml: *const Branch,
3844 state: *mut c_void,
3845 cb: extern "C" fn(*mut c_void, *const YXmlTextEvent),
3846) -> *mut Subscription {
3847 assert!(!xml.is_null());
3848
3849 let state = CallbackState::new(state);
3850 let xml = XmlTextRef::from_raw_branch(xml);
3851 let subscription = xml.observe(move |txn, e| {
3852 let e = YXmlTextEvent::new(e, txn);
3853 cb(state.0, &e as *const YXmlTextEvent);
3854 });
3855 Box::into_raw(Box::new(subscription))
3856}
3857
3858#[no_mangle]
3865pub unsafe extern "C" fn yobserve_deep(
3866 ytype: *mut Branch,
3867 state: *mut c_void,
3868 cb: extern "C" fn(*mut c_void, u32, *const YEvent),
3869) -> *mut Subscription {
3870 assert!(!ytype.is_null());
3871
3872 let state = CallbackState::new(state);
3873 let branch = ytype.as_mut().unwrap();
3874 let subscription = branch.observe_deep(move |txn, events| {
3875 let events: Vec<_> = events.iter().map(|e| YEvent::new(txn, e)).collect();
3876 let len = events.len() as u32;
3877 cb(state.0, len, events.as_ptr());
3878 });
3879 Box::into_raw(Box::new(subscription))
3880}
3881
3882#[repr(C)]
3885pub struct YAfterTransactionEvent {
3886 pub before_state: YStateVector,
3888 pub after_state: YStateVector,
3890 pub delete_set: YDeleteSet,
3892}
3893
3894impl YAfterTransactionEvent {
3895 unsafe fn new(e: &TransactionCleanupEvent) -> Self {
3896 YAfterTransactionEvent {
3897 before_state: YStateVector::new(&e.before_state),
3898 after_state: YStateVector::new(&e.after_state),
3899 delete_set: YDeleteSet::new(&e.delete_set),
3900 }
3901 }
3902}
3903
3904#[repr(C)]
3905pub struct YSubdocsEvent {
3906 added_len: u32,
3907 removed_len: u32,
3908 loaded_len: u32,
3909 added: *mut *mut Doc,
3910 removed: *mut *mut Doc,
3911 loaded: *mut *mut Doc,
3912}
3913
3914impl YSubdocsEvent {
3915 unsafe fn new(e: &SubdocsEvent) -> Self {
3916 fn into_ptr(v: SubdocsEventIter) -> *mut *mut Doc {
3917 let array: Vec<_> = v.map(|doc| Box::into_raw(Box::new(doc.clone()))).collect();
3918 let mut boxed = array.into_boxed_slice();
3919 let ptr = boxed.as_mut_ptr();
3920 forget(boxed);
3921 ptr
3922 }
3923
3924 let added = e.added();
3925 let removed = e.removed();
3926 let loaded = e.loaded();
3927
3928 YSubdocsEvent {
3929 added_len: added.len() as u32,
3930 removed_len: removed.len() as u32,
3931 loaded_len: loaded.len() as u32,
3932 added: into_ptr(added),
3933 removed: into_ptr(removed),
3934 loaded: into_ptr(loaded),
3935 }
3936 }
3937}
3938
3939impl Drop for YSubdocsEvent {
3940 fn drop(&mut self) {
3941 fn release(len: u32, buf: *mut *mut Doc) {
3942 unsafe {
3943 let docs = Vec::from_raw_parts(buf, len as usize, len as usize);
3944 for d in docs {
3945 drop(Box::from_raw(d));
3946 }
3947 }
3948 }
3949
3950 release(self.added_len, self.added);
3951 release(self.removed_len, self.removed);
3952 release(self.loaded_len, self.loaded);
3953 }
3954}
3955
3956#[repr(C)]
3959pub struct YStateVector {
3960 pub entries_count: u32,
3962 pub client_ids: *mut u64,
3966 pub clocks: *mut u32,
3970}
3971
3972impl YStateVector {
3973 unsafe fn new(sv: &StateVector) -> Self {
3974 let entries_count = sv.len() as u32;
3975 let mut client_ids = Vec::with_capacity(sv.len());
3976 let mut clocks = Vec::with_capacity(sv.len());
3977 for (&client, &clock) in sv.iter() {
3978 client_ids.push(client as u64);
3979 clocks.push(clock as u32);
3980 }
3981
3982 YStateVector {
3983 entries_count,
3984 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
3985 clocks: Box::into_raw(clocks.into_boxed_slice()) as *mut _,
3986 }
3987 }
3988}
3989
3990impl Drop for YStateVector {
3991 fn drop(&mut self) {
3992 let len = self.entries_count as usize;
3993 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
3994 drop(unsafe { Vec::from_raw_parts(self.clocks, len, len) });
3995 }
3996}
3997
3998#[repr(C)]
4002pub struct YDeleteSet {
4003 pub entries_count: u32,
4005 pub client_ids: *mut u64,
4009 pub ranges: *mut YIdRangeSeq,
4013}
4014
4015impl YDeleteSet {
4016 unsafe fn new(ds: &DeleteSet) -> Self {
4017 let len = ds.len();
4018 let mut client_ids = Vec::with_capacity(len);
4019 let mut ranges = Vec::with_capacity(len);
4020
4021 for (&client, range) in ds.iter() {
4022 client_ids.push(client);
4023 let seq: Vec<_> = range
4024 .iter()
4025 .map(|r| YIdRange {
4026 start: r.start as u32,
4027 end: r.end as u32,
4028 })
4029 .collect();
4030 ranges.push(YIdRangeSeq {
4031 len: seq.len() as u32,
4032 seq: Box::into_raw(seq.into_boxed_slice()) as *mut _,
4033 })
4034 }
4035
4036 YDeleteSet {
4037 entries_count: len as u32,
4038 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
4039 ranges: Box::into_raw(ranges.into_boxed_slice()) as *mut _,
4040 }
4041 }
4042}
4043
4044impl Drop for YDeleteSet {
4045 fn drop(&mut self) {
4046 let len = self.entries_count as usize;
4047 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
4048 drop(unsafe { Vec::from_raw_parts(self.ranges, len, len) });
4049 }
4050}
4051
4052#[repr(C)]
4055pub struct YIdRangeSeq {
4056 pub len: u32,
4058 pub seq: *mut YIdRange,
4062}
4063
4064impl Drop for YIdRangeSeq {
4065 fn drop(&mut self) {
4066 let len = self.len as usize;
4067 drop(unsafe { Vec::from_raw_parts(self.seq, len, len) })
4068 }
4069}
4070
4071#[repr(C)]
4072pub struct YIdRange {
4073 pub start: u32,
4074 pub end: u32,
4075}
4076
4077#[repr(C)]
4078pub struct YEvent {
4079 pub tag: i8,
4087
4088 pub content: YEventContent,
4091}
4092
4093impl YEvent {
4094 fn new<'doc>(txn: &yrs::TransactionMut<'doc>, e: &Event) -> YEvent {
4095 match e {
4096 Event::Text(e) => YEvent {
4097 tag: Y_TEXT,
4098 content: YEventContent {
4099 text: YTextEvent::new(e, txn),
4100 },
4101 },
4102 Event::Array(e) => YEvent {
4103 tag: Y_ARRAY,
4104 content: YEventContent {
4105 array: YArrayEvent::new(e, txn),
4106 },
4107 },
4108 Event::Map(e) => YEvent {
4109 tag: Y_MAP,
4110 content: YEventContent {
4111 map: YMapEvent::new(e, txn),
4112 },
4113 },
4114 Event::XmlFragment(e) => YEvent {
4115 tag: if let XmlOut::Fragment(_) = e.target() {
4116 Y_XML_FRAG
4117 } else {
4118 Y_XML_ELEM
4119 },
4120 content: YEventContent {
4121 xml_elem: YXmlEvent::new(e, txn),
4122 },
4123 },
4124 Event::XmlText(e) => YEvent {
4125 tag: Y_XML_TEXT,
4126 content: YEventContent {
4127 xml_text: YXmlTextEvent::new(e, txn),
4128 },
4129 },
4130 Event::Weak(e) => YEvent {
4131 tag: Y_WEAK_LINK,
4132 content: YEventContent {
4133 weak: YWeakLinkEvent::new(e, txn),
4134 },
4135 },
4136 }
4137 }
4138}
4139
4140#[repr(C)]
4141pub union YEventContent {
4142 pub text: YTextEvent,
4143 pub map: YMapEvent,
4144 pub array: YArrayEvent,
4145 pub xml_elem: YXmlEvent,
4146 pub xml_text: YXmlTextEvent,
4147 pub weak: YWeakLinkEvent,
4148}
4149
4150#[repr(C)]
4154#[derive(Copy, Clone)]
4155pub struct YTextEvent {
4156 inner: *const c_void,
4157 txn: *const yrs::TransactionMut<'static>,
4158}
4159
4160impl YTextEvent {
4161 fn new<'dev>(inner: &TextEvent, txn: &yrs::TransactionMut<'dev>) -> Self {
4162 let inner = inner as *const TextEvent as *const _;
4163 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4164 let txn = txn as *const _;
4165 YTextEvent { inner, txn }
4166 }
4167
4168 fn txn(&self) -> &yrs::TransactionMut {
4169 unsafe { self.txn.as_ref().unwrap() }
4170 }
4171}
4172
4173impl Deref for YTextEvent {
4174 type Target = TextEvent;
4175
4176 fn deref(&self) -> &Self::Target {
4177 unsafe { (self.inner as *const TextEvent).as_ref().unwrap() }
4178 }
4179}
4180
4181#[repr(C)]
4185#[derive(Copy, Clone)]
4186pub struct YArrayEvent {
4187 inner: *const c_void,
4188 txn: *const yrs::TransactionMut<'static>,
4189}
4190
4191impl YArrayEvent {
4192 fn new<'doc>(inner: &ArrayEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4193 let inner = inner as *const ArrayEvent as *const _;
4194 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4195 let txn = txn as *const _;
4196 YArrayEvent { inner, txn }
4197 }
4198
4199 fn txn(&self) -> &yrs::TransactionMut {
4200 unsafe { self.txn.as_ref().unwrap() }
4201 }
4202}
4203
4204impl Deref for YArrayEvent {
4205 type Target = ArrayEvent;
4206
4207 fn deref(&self) -> &Self::Target {
4208 unsafe { (self.inner as *const ArrayEvent).as_ref().unwrap() }
4209 }
4210}
4211
4212#[repr(C)]
4216#[derive(Copy, Clone)]
4217pub struct YMapEvent {
4218 inner: *const c_void,
4219 txn: *const yrs::TransactionMut<'static>,
4220}
4221
4222impl YMapEvent {
4223 fn new<'doc>(inner: &MapEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4224 let inner = inner as *const MapEvent as *const _;
4225 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4226 let txn = txn as *const _;
4227 YMapEvent { inner, txn }
4228 }
4229
4230 fn txn(&self) -> &yrs::TransactionMut<'static> {
4231 unsafe { self.txn.as_ref().unwrap() }
4232 }
4233}
4234
4235impl Deref for YMapEvent {
4236 type Target = MapEvent;
4237
4238 fn deref(&self) -> &Self::Target {
4239 unsafe { (self.inner as *const MapEvent).as_ref().unwrap() }
4240 }
4241}
4242
4243#[repr(C)]
4248#[derive(Copy, Clone)]
4249pub struct YXmlEvent {
4250 inner: *const c_void,
4251 txn: *const yrs::TransactionMut<'static>,
4252}
4253
4254impl YXmlEvent {
4255 fn new<'doc>(inner: &XmlEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4256 let inner = inner as *const XmlEvent as *const _;
4257 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4258 let txn = txn as *const _;
4259 YXmlEvent { inner, txn }
4260 }
4261
4262 fn txn(&self) -> &yrs::TransactionMut<'static> {
4263 unsafe { self.txn.as_ref().unwrap() }
4264 }
4265}
4266
4267impl Deref for YXmlEvent {
4268 type Target = XmlEvent;
4269
4270 fn deref(&self) -> &Self::Target {
4271 unsafe { (self.inner as *const XmlEvent).as_ref().unwrap() }
4272 }
4273}
4274
4275#[repr(C)]
4280#[derive(Copy, Clone)]
4281pub struct YXmlTextEvent {
4282 inner: *const c_void,
4283 txn: *const yrs::TransactionMut<'static>,
4284}
4285
4286impl YXmlTextEvent {
4287 fn new<'doc>(inner: &XmlTextEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4288 let inner = inner as *const XmlTextEvent as *const _;
4289 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4290 let txn = txn as *const _;
4291 YXmlTextEvent { inner, txn }
4292 }
4293
4294 fn txn(&self) -> &yrs::TransactionMut<'static> {
4295 unsafe { self.txn.as_ref().unwrap() }
4296 }
4297}
4298
4299impl Deref for YXmlTextEvent {
4300 type Target = XmlTextEvent;
4301
4302 fn deref(&self) -> &Self::Target {
4303 unsafe { (self.inner as *const XmlTextEvent).as_ref().unwrap() }
4304 }
4305}
4306
4307#[repr(C)]
4310#[derive(Copy, Clone)]
4311pub struct YWeakLinkEvent {
4312 inner: *const c_void,
4313 txn: *const yrs::TransactionMut<'static>,
4314}
4315
4316impl YWeakLinkEvent {
4317 fn new<'doc>(inner: &WeakEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4318 let inner = inner as *const WeakEvent as *const _;
4319 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4320 let txn = txn as *const _;
4321 YWeakLinkEvent { inner, txn }
4322 }
4323}
4324
4325impl Deref for YWeakLinkEvent {
4326 type Target = WeakEvent;
4327
4328 fn deref(&self) -> &Self::Target {
4329 unsafe { (self.inner as *const WeakEvent).as_ref().unwrap() }
4330 }
4331}
4332
4333#[no_mangle]
4335pub unsafe extern "C" fn ytext_event_target(e: *const YTextEvent) -> *mut Branch {
4336 assert!(!e.is_null());
4337 let out = (&*e).target().clone();
4338 out.into_raw_branch()
4339}
4340
4341#[no_mangle]
4343pub unsafe extern "C" fn yarray_event_target(e: *const YArrayEvent) -> *mut Branch {
4344 assert!(!e.is_null());
4345 let out = (&*e).target().clone();
4346 out.into_raw_branch()
4347}
4348
4349#[no_mangle]
4351pub unsafe extern "C" fn ymap_event_target(e: *const YMapEvent) -> *mut Branch {
4352 assert!(!e.is_null());
4353 let out = (&*e).target().clone();
4354 out.into_raw_branch()
4355}
4356
4357#[no_mangle]
4359pub unsafe extern "C" fn yxmlelem_event_target(e: *const YXmlEvent) -> *mut Branch {
4360 assert!(!e.is_null());
4361 let out = (&*e).target().clone();
4362 match out {
4363 XmlOut::Element(e) => e.into_raw_branch(),
4364 XmlOut::Fragment(e) => e.into_raw_branch(),
4365 XmlOut::Text(e) => e.into_raw_branch(),
4366 }
4367}
4368
4369#[no_mangle]
4371pub unsafe extern "C" fn yxmltext_event_target(e: *const YXmlTextEvent) -> *mut Branch {
4372 assert!(!e.is_null());
4373 let out = (&*e).target().clone();
4374 out.into_raw_branch()
4375}
4376
4377#[no_mangle]
4384pub unsafe extern "C" fn ytext_event_path(
4385 e: *const YTextEvent,
4386 len: *mut u32,
4387) -> *mut YPathSegment {
4388 assert!(!e.is_null());
4389 let e = &*e;
4390 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4391 let out = path.into_boxed_slice();
4392 *len = out.len() as u32;
4393 Box::into_raw(out) as *mut _
4394}
4395
4396#[no_mangle]
4403pub unsafe extern "C" fn ymap_event_path(e: *const YMapEvent, len: *mut u32) -> *mut YPathSegment {
4404 assert!(!e.is_null());
4405 let e = &*e;
4406 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4407 let out = path.into_boxed_slice();
4408 *len = out.len() as u32;
4409 Box::into_raw(out) as *mut _
4410}
4411
4412#[no_mangle]
4419pub unsafe extern "C" fn yxmlelem_event_path(
4420 e: *const YXmlEvent,
4421 len: *mut u32,
4422) -> *mut YPathSegment {
4423 assert!(!e.is_null());
4424 let e = &*e;
4425 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4426 let out = path.into_boxed_slice();
4427 *len = out.len() as u32;
4428 Box::into_raw(out) as *mut _
4429}
4430
4431#[no_mangle]
4438pub unsafe extern "C" fn yxmltext_event_path(
4439 e: *const YXmlTextEvent,
4440 len: *mut u32,
4441) -> *mut YPathSegment {
4442 assert!(!e.is_null());
4443 let e = &*e;
4444 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4445 let out = path.into_boxed_slice();
4446 *len = out.len() as u32;
4447 Box::into_raw(out) as *mut _
4448}
4449
4450#[no_mangle]
4457pub unsafe extern "C" fn yarray_event_path(
4458 e: *const YArrayEvent,
4459 len: *mut u32,
4460) -> *mut YPathSegment {
4461 assert!(!e.is_null());
4462 let e = &*e;
4463 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4464 let out = path.into_boxed_slice();
4465 *len = out.len() as u32;
4466 Box::into_raw(out) as *mut _
4467}
4468
4469#[no_mangle]
4472pub unsafe extern "C" fn ypath_destroy(path: *mut YPathSegment, len: u32) {
4473 if !path.is_null() {
4474 drop(Vec::from_raw_parts(path, len as usize, len as usize));
4475 }
4476}
4477
4478#[no_mangle]
4485pub unsafe extern "C" fn ytext_event_delta(e: *const YTextEvent, len: *mut u32) -> *mut YDeltaOut {
4486 assert!(!e.is_null());
4487 let e = &*e;
4488 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4489
4490 let out = delta.into_boxed_slice();
4491 *len = out.len() as u32;
4492 Box::into_raw(out) as *mut _
4493}
4494
4495#[no_mangle]
4502pub unsafe extern "C" fn yxmltext_event_delta(
4503 e: *const YXmlTextEvent,
4504 len: *mut u32,
4505) -> *mut YDeltaOut {
4506 assert!(!e.is_null());
4507 let e = &*e;
4508 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4509
4510 let out = delta.into_boxed_slice();
4511 *len = out.len() as u32;
4512 Box::into_raw(out) as *mut _
4513}
4514
4515#[no_mangle]
4522pub unsafe extern "C" fn yarray_event_delta(
4523 e: *const YArrayEvent,
4524 len: *mut u32,
4525) -> *mut YEventChange {
4526 assert!(!e.is_null());
4527 let e = &*e;
4528 let delta: Vec<_> = e
4529 .delta(e.txn())
4530 .into_iter()
4531 .map(YEventChange::from)
4532 .collect();
4533
4534 let out = delta.into_boxed_slice();
4535 *len = out.len() as u32;
4536 Box::into_raw(out) as *mut _
4537}
4538
4539#[no_mangle]
4546pub unsafe extern "C" fn yxmlelem_event_delta(
4547 e: *const YXmlEvent,
4548 len: *mut u32,
4549) -> *mut YEventChange {
4550 assert!(!e.is_null());
4551 let e = &*e;
4552 let delta: Vec<_> = e
4553 .delta(e.txn())
4554 .into_iter()
4555 .map(YEventChange::from)
4556 .collect();
4557
4558 let out = delta.into_boxed_slice();
4559 *len = out.len() as u32;
4560 Box::into_raw(out) as *mut _
4561}
4562
4563#[no_mangle]
4565pub unsafe extern "C" fn ytext_delta_destroy(delta: *mut YDeltaOut, len: u32) {
4566 if !delta.is_null() {
4567 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4568 drop(delta);
4569 }
4570}
4571
4572#[no_mangle]
4574pub unsafe extern "C" fn yevent_delta_destroy(delta: *mut YEventChange, len: u32) {
4575 if !delta.is_null() {
4576 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4577 drop(delta);
4578 }
4579}
4580
4581#[no_mangle]
4588pub unsafe extern "C" fn ymap_event_keys(
4589 e: *const YMapEvent,
4590 len: *mut u32,
4591) -> *mut YEventKeyChange {
4592 assert!(!e.is_null());
4593 let e = &*e;
4594 let delta: Vec<_> = e
4595 .keys(e.txn())
4596 .into_iter()
4597 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4598 .collect();
4599
4600 let out = delta.into_boxed_slice();
4601 *len = out.len() as u32;
4602 Box::into_raw(out) as *mut _
4603}
4604
4605#[no_mangle]
4611pub unsafe extern "C" fn yxmlelem_event_keys(
4612 e: *const YXmlEvent,
4613 len: *mut u32,
4614) -> *mut YEventKeyChange {
4615 assert!(!e.is_null());
4616 let e = &*e;
4617 let delta: Vec<_> = e
4618 .keys(e.txn())
4619 .into_iter()
4620 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4621 .collect();
4622
4623 let out = delta.into_boxed_slice();
4624 *len = out.len() as u32;
4625 Box::into_raw(out) as *mut _
4626}
4627
4628#[no_mangle]
4634pub unsafe extern "C" fn yxmltext_event_keys(
4635 e: *const YXmlTextEvent,
4636 len: *mut u32,
4637) -> *mut YEventKeyChange {
4638 assert!(!e.is_null());
4639 let e = &*e;
4640 let delta: Vec<_> = e
4641 .keys(e.txn())
4642 .into_iter()
4643 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4644 .collect();
4645
4646 let out = delta.into_boxed_slice();
4647 *len = out.len() as u32;
4648 Box::into_raw(out) as *mut _
4649}
4650
4651#[no_mangle]
4654pub unsafe extern "C" fn yevent_keys_destroy(keys: *mut YEventKeyChange, len: u32) {
4655 if !keys.is_null() {
4656 drop(Vec::from_raw_parts(keys, len as usize, len as usize));
4657 }
4658}
4659
4660pub type YUndoManager = yrs::undo::UndoManager<AtomicPtr<c_void>>;
4661
4662#[repr(C)]
4663pub struct YUndoManagerOptions {
4664 pub capture_timeout_millis: i32,
4665}
4666
4667#[no_mangle]
4675pub unsafe extern "C" fn yundo_manager(
4676 doc: *const Doc,
4677 options: *const YUndoManagerOptions,
4678) -> *mut YUndoManager {
4679 let doc = doc.as_ref().unwrap();
4680
4681 let mut o = yrs::undo::Options::default();
4682 if let Some(options) = options.as_ref() {
4683 if options.capture_timeout_millis >= 0 {
4684 o.capture_timeout_millis = options.capture_timeout_millis as u64;
4685 }
4686 };
4687 let boxed = Box::new(yrs::undo::UndoManager::with_options(doc, o));
4688 Box::into_raw(boxed)
4689}
4690
4691#[no_mangle]
4693pub unsafe extern "C" fn yundo_manager_destroy(mgr: *mut YUndoManager) {
4694 drop(Box::from_raw(mgr));
4695}
4696
4697#[no_mangle]
4702pub unsafe extern "C" fn yundo_manager_add_origin(
4703 mgr: *mut YUndoManager,
4704 origin_len: u32,
4705 origin: *const c_char,
4706) {
4707 let mgr = mgr.as_mut().unwrap();
4708 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4709 mgr.include_origin(Origin::from(bytes));
4710}
4711
4712#[no_mangle]
4714pub unsafe extern "C" fn yundo_manager_remove_origin(
4715 mgr: *mut YUndoManager,
4716 origin_len: u32,
4717 origin: *const c_char,
4718) {
4719 let mgr = mgr.as_mut().unwrap();
4720 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4721 mgr.exclude_origin(Origin::from(bytes));
4722}
4723
4724#[no_mangle]
4726pub unsafe extern "C" fn yundo_manager_add_scope(mgr: *mut YUndoManager, ytype: *const Branch) {
4727 let mgr = mgr.as_mut().unwrap();
4728 let branch = ytype.as_ref().unwrap();
4729 mgr.expand_scope(&BranchPtr::from(branch));
4730}
4731
4732#[no_mangle]
4741pub unsafe extern "C" fn yundo_manager_clear(mgr: *mut YUndoManager) {
4742 let mgr = mgr.as_mut().unwrap();
4743 mgr.clear();
4744}
4745
4746#[no_mangle]
4753pub unsafe extern "C" fn yundo_manager_stop(mgr: *mut YUndoManager) {
4754 let mgr = mgr.as_mut().unwrap();
4755 mgr.reset();
4756}
4757
4758#[no_mangle]
4765pub unsafe extern "C" fn yundo_manager_undo(mgr: *mut YUndoManager) -> u8 {
4766 let mgr = mgr.as_mut().unwrap();
4767
4768 match mgr.try_undo() {
4769 Ok(true) => Y_TRUE,
4770 Ok(false) => Y_FALSE,
4771 Err(_) => Y_FALSE,
4772 }
4773}
4774
4775#[no_mangle]
4781pub unsafe extern "C" fn yundo_manager_redo(mgr: *mut YUndoManager) -> u8 {
4782 let mgr = mgr.as_mut().unwrap();
4783 match mgr.try_redo() {
4784 Ok(true) => Y_TRUE,
4785 Ok(false) => Y_FALSE,
4786 Err(_) => Y_FALSE,
4787 }
4788}
4789
4790#[no_mangle]
4792pub unsafe extern "C" fn yundo_manager_undo_stack_len(mgr: *mut YUndoManager) -> u32 {
4793 let mgr = mgr.as_mut().unwrap();
4794 mgr.undo_stack().len() as u32
4795}
4796
4797#[no_mangle]
4799pub unsafe extern "C" fn yundo_manager_redo_stack_len(mgr: *mut YUndoManager) -> u32 {
4800 let mgr = mgr.as_mut().unwrap();
4801 mgr.redo_stack().len() as u32
4802}
4803
4804#[no_mangle]
4810pub unsafe extern "C" fn yundo_manager_observe_added(
4811 mgr: *mut YUndoManager,
4812 state: *mut c_void,
4813 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4814) -> *mut Subscription {
4815 let state = CallbackState::new(state);
4816 let mgr = mgr.as_mut().unwrap();
4817 let subscription = mgr.observe_item_added(move |_, e| {
4818 let meta_ptr = {
4819 let event = YUndoEvent::new(e);
4820 callback(state.0, &event as *const YUndoEvent);
4821 event.meta
4822 };
4823 e.meta().store(meta_ptr, Ordering::Release);
4824 });
4825 Box::into_raw(Box::new(subscription))
4826}
4827
4828#[no_mangle]
4834pub unsafe extern "C" fn yundo_manager_observe_popped(
4835 mgr: *mut YUndoManager,
4836 state: *mut c_void,
4837 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4838) -> *mut Subscription {
4839 let mgr = mgr.as_mut().unwrap();
4840 let state = CallbackState::new(state);
4841 let subscription = mgr
4842 .observe_item_popped(move |_, e| {
4843 let meta_ptr = {
4844 let event = YUndoEvent::new(e);
4845 callback(state.0, &event as *const YUndoEvent);
4846 event.meta
4847 };
4848 e.meta().store(meta_ptr, Ordering::Release);
4849 })
4850 .into();
4851 Box::into_raw(Box::new(subscription))
4852}
4853
4854pub const Y_KIND_UNDO: c_char = 0;
4855pub const Y_KIND_REDO: c_char = 1;
4856
4857#[repr(C)]
4861pub struct YUndoEvent {
4862 pub kind: c_char,
4865 pub origin: *const c_char,
4868 pub origin_len: u32,
4872 pub meta: *mut c_void,
4882}
4883
4884impl YUndoEvent {
4885 unsafe fn new(e: &yrs::undo::Event<AtomicPtr<c_void>>) -> Self {
4886 let (origin, origin_len) = if let Some(origin) = e.origin() {
4887 let bytes = origin.as_ref();
4888 let origin_len = bytes.len() as u32;
4889 let origin = bytes.as_ptr() as *const c_char;
4890 (origin, origin_len)
4891 } else {
4892 (null(), 0)
4893 };
4894 YUndoEvent {
4895 kind: match e.kind() {
4896 EventKind::Undo => Y_KIND_UNDO,
4897 EventKind::Redo => Y_KIND_REDO,
4898 },
4899 origin,
4900 origin_len,
4901 meta: e.meta().load(Ordering::Acquire),
4902 }
4903 }
4904}
4905
4906#[no_mangle]
4910pub unsafe extern "C" fn ytype_kind(branch: *const Branch) -> i8 {
4911 if let Some(branch) = branch.as_ref() {
4912 match branch.type_ref() {
4913 TypeRef::Array => Y_ARRAY,
4914 TypeRef::Map => Y_MAP,
4915 TypeRef::Text => Y_TEXT,
4916 TypeRef::XmlElement(_) => Y_XML_ELEM,
4917 TypeRef::XmlText => Y_XML_TEXT,
4918 TypeRef::XmlFragment => Y_XML_FRAG,
4919 TypeRef::SubDoc => Y_DOC,
4920 TypeRef::WeakLink(_) => Y_WEAK_LINK,
4921 TypeRef::XmlHook => 0,
4922 TypeRef::Undefined => 0,
4923 }
4924 } else {
4925 0
4926 }
4927}
4928
4929pub const Y_EVENT_PATH_KEY: c_char = 1;
4931
4932pub const Y_EVENT_PATH_INDEX: c_char = 2;
4934
4935#[repr(C)]
4943pub struct YPathSegment {
4944 pub tag: c_char,
4952
4953 pub value: YPathSegmentCase,
4956}
4957
4958impl From<PathSegment> for YPathSegment {
4959 fn from(ps: PathSegment) -> Self {
4960 match ps {
4961 PathSegment::Key(key) => {
4962 let key = CString::new(key.as_ref()).unwrap().into_raw() as *const _;
4963 YPathSegment {
4964 tag: Y_EVENT_PATH_KEY,
4965 value: YPathSegmentCase { key },
4966 }
4967 }
4968 PathSegment::Index(index) => YPathSegment {
4969 tag: Y_EVENT_PATH_INDEX,
4970 value: YPathSegmentCase {
4971 index: index as u32,
4972 },
4973 },
4974 }
4975 }
4976}
4977
4978impl Drop for YPathSegment {
4979 fn drop(&mut self) {
4980 if self.tag == Y_EVENT_PATH_KEY {
4981 unsafe {
4982 ystring_destroy(self.value.key as *mut _);
4983 }
4984 }
4985 }
4986}
4987
4988#[repr(C)]
4989pub union YPathSegmentCase {
4990 pub key: *const c_char,
4991 pub index: u32,
4992}
4993
4994pub const Y_EVENT_CHANGE_ADD: u8 = 1;
4997
4998pub const Y_EVENT_CHANGE_DELETE: u8 = 2;
5001
5002pub const Y_EVENT_CHANGE_RETAIN: u8 = 3;
5005
5006#[repr(C)]
5022pub struct YEventChange {
5023 pub tag: u8,
5033
5034 pub len: u32,
5037
5038 pub values: *const YOutput,
5041}
5042
5043impl<'a> From<&'a Change> for YEventChange {
5044 fn from(change: &'a Change) -> Self {
5045 match change {
5046 Change::Added(values) => {
5047 let out: Vec<_> = values
5048 .into_iter()
5049 .map(|v| YOutput::from(v.clone()))
5050 .collect();
5051 let len = out.len() as u32;
5052 let out = out.into_boxed_slice();
5053 let values = Box::into_raw(out) as *mut _;
5054
5055 YEventChange {
5056 tag: Y_EVENT_CHANGE_ADD,
5057 len,
5058 values,
5059 }
5060 }
5061 Change::Removed(len) => YEventChange {
5062 tag: Y_EVENT_CHANGE_DELETE,
5063 len: *len as u32,
5064 values: null(),
5065 },
5066 Change::Retain(len) => YEventChange {
5067 tag: Y_EVENT_CHANGE_RETAIN,
5068 len: *len as u32,
5069 values: null(),
5070 },
5071 }
5072 }
5073}
5074
5075impl Drop for YEventChange {
5076 fn drop(&mut self) {
5077 if self.tag == Y_EVENT_CHANGE_ADD {
5078 unsafe {
5079 let len = self.len as usize;
5080 let values = Vec::from_raw_parts(self.values as *mut YOutput, len, len);
5081 drop(values);
5082 }
5083 }
5084 }
5085}
5086
5087#[repr(C)]
5106pub struct YDeltaOut {
5107 pub tag: u8,
5117
5118 pub len: u32,
5121
5122 pub attributes_len: u32,
5124
5125 pub attributes: *mut YDeltaAttr,
5128
5129 pub insert: *mut YOutput,
5132}
5133
5134impl YDeltaOut {
5135 fn insert(value: &Out, attrs: &Option<Box<Attrs>>) -> Self {
5136 let insert = Box::into_raw(Box::new(YOutput::from(value.clone())));
5137 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5138 let len = attrs.len() as u32;
5139 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5140 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5141 (len, attrs)
5142 } else {
5143 (0, null_mut())
5144 };
5145
5146 YDeltaOut {
5147 tag: Y_EVENT_CHANGE_ADD,
5148 len: 1,
5149 insert,
5150 attributes_len,
5151 attributes,
5152 }
5153 }
5154
5155 fn retain(len: u32, attrs: &Option<Box<Attrs>>) -> Self {
5156 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5157 let len = attrs.len() as u32;
5158 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5159 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5160 (len, attrs)
5161 } else {
5162 (0, null_mut())
5163 };
5164 YDeltaOut {
5165 tag: Y_EVENT_CHANGE_RETAIN,
5166 len,
5167 insert: null_mut(),
5168 attributes_len,
5169 attributes,
5170 }
5171 }
5172
5173 fn delete(len: u32) -> Self {
5174 YDeltaOut {
5175 tag: Y_EVENT_CHANGE_DELETE,
5176 len,
5177 insert: null_mut(),
5178 attributes_len: 0,
5179 attributes: null_mut(),
5180 }
5181 }
5182}
5183
5184impl<'a> From<&'a Delta> for YDeltaOut {
5185 fn from(d: &Delta) -> Self {
5186 match d {
5187 Delta::Inserted(value, attrs) => YDeltaOut::insert(value, attrs),
5188 Delta::Retain(len, attrs) => YDeltaOut::retain(*len, attrs),
5189 Delta::Deleted(len) => YDeltaOut::delete(*len),
5190 }
5191 }
5192}
5193
5194impl Drop for YDeltaOut {
5195 fn drop(&mut self) {
5196 unsafe {
5197 if !self.attributes.is_null() {
5198 let len = self.attributes_len as usize;
5199 drop(Vec::from_raw_parts(self.attributes, len, len));
5200 }
5201 if !self.insert.is_null() {
5202 drop(Box::from_raw(self.insert));
5203 }
5204 }
5205 }
5206}
5207
5208#[repr(C)]
5210pub struct YDeltaAttr {
5211 pub key: *const c_char,
5213 pub value: YOutput,
5215}
5216
5217impl YDeltaAttr {
5218 fn new(k: &Arc<str>, v: &Any) -> Self {
5219 let key = CString::new(k.as_ref()).unwrap().into_raw() as *const _;
5220 let value = YOutput::from(v);
5221 YDeltaAttr { key, value }
5222 }
5223}
5224
5225impl Drop for YDeltaAttr {
5226 fn drop(&mut self) {
5227 unsafe { ystring_destroy(self.key as *mut _) }
5228 }
5229}
5230
5231#[repr(C)]
5246pub struct YDeltaIn {
5247 pub tag: u8,
5257
5258 pub len: u32,
5261
5262 pub attributes: *const YInput,
5265
5266 pub insert: *const YInput,
5269}
5270
5271impl YDeltaIn {
5272 fn as_input(&self) -> Delta<YInput> {
5273 match self.tag {
5274 Y_EVENT_CHANGE_RETAIN => {
5275 let attrs = if self.attributes.is_null() {
5276 None
5277 } else {
5278 let attrs = unsafe { self.attributes.read() };
5279 map_attrs(attrs.into()).map(Box::new)
5280 };
5281 Delta::Retain(self.len, attrs)
5282 }
5283 Y_EVENT_CHANGE_DELETE => Delta::Deleted(self.len),
5284 Y_EVENT_CHANGE_ADD => {
5285 let attrs = if self.attributes.is_null() {
5286 None
5287 } else {
5288 let attrs = unsafe { self.attributes.read() };
5289 map_attrs(attrs.into()).map(Box::new)
5290 };
5291 let input = unsafe { self.insert.read() };
5292 Delta::Inserted(input, attrs)
5293 }
5294 tag => panic!("YDelta tag identifier is of unknown type: {}", tag),
5295 }
5296 }
5297}
5298
5299pub const Y_EVENT_KEY_CHANGE_ADD: c_char = 4;
5302
5303pub const Y_EVENT_KEY_CHANGE_DELETE: c_char = 5;
5306
5307pub const Y_EVENT_KEY_CHANGE_UPDATE: c_char = 6;
5310
5311#[repr(C)]
5324pub struct YEventKeyChange {
5325 pub key: *const c_char,
5327 pub tag: c_char,
5337
5338 pub old_value: *const YOutput,
5340
5341 pub new_value: *const YOutput,
5343}
5344
5345impl YEventKeyChange {
5346 fn new(key: &str, change: &EntryChange) -> Self {
5347 let key = CString::new(key).unwrap().into_raw() as *const _;
5348 match change {
5349 EntryChange::Inserted(new) => YEventKeyChange {
5350 key,
5351 tag: Y_EVENT_KEY_CHANGE_ADD,
5352 old_value: null(),
5353 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5354 },
5355 EntryChange::Updated(old, new) => YEventKeyChange {
5356 key,
5357 tag: Y_EVENT_KEY_CHANGE_UPDATE,
5358 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5359 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5360 },
5361 EntryChange::Removed(old) => YEventKeyChange {
5362 key,
5363 tag: Y_EVENT_KEY_CHANGE_DELETE,
5364 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5365 new_value: null(),
5366 },
5367 }
5368 }
5369}
5370
5371impl Drop for YEventKeyChange {
5372 fn drop(&mut self) {
5373 unsafe {
5374 ystring_destroy(self.key as *mut _);
5375 youtput_destroy(self.old_value as *mut _);
5376 youtput_destroy(self.new_value as *mut _);
5377 }
5378 }
5379}
5380
5381trait BranchPointable {
5382 fn into_raw_branch(self) -> *mut Branch;
5383 fn from_raw_branch(branch: *const Branch) -> Self;
5384}
5385
5386impl<T> BranchPointable for T
5387where
5388 T: AsRef<Branch> + From<BranchPtr>,
5389{
5390 fn into_raw_branch(self) -> *mut Branch {
5391 let branch_ref = self.as_ref();
5392 branch_ref as *const Branch as *mut Branch
5393 }
5394
5395 fn from_raw_branch(branch: *const Branch) -> Self {
5396 let b = unsafe { branch.as_ref().unwrap() };
5397 let branch_ref = BranchPtr::from(b);
5398 T::from(branch_ref)
5399 }
5400}
5401
5402#[repr(transparent)]
5413pub struct YStickyIndex(StickyIndex);
5414
5415impl From<StickyIndex> for YStickyIndex {
5416 #[inline(always)]
5417 fn from(value: StickyIndex) -> Self {
5418 YStickyIndex(value)
5419 }
5420}
5421
5422#[no_mangle]
5424pub unsafe extern "C" fn ysticky_index_destroy(pos: *mut YStickyIndex) {
5425 drop(Box::from_raw(pos))
5426}
5427
5428#[no_mangle]
5432pub unsafe extern "C" fn ysticky_index_assoc(pos: *const YStickyIndex) -> i8 {
5433 let pos = pos.as_ref().unwrap();
5434 match pos.0.assoc {
5435 Assoc::After => 0,
5436 Assoc::Before => -1,
5437 }
5438}
5439
5440#[no_mangle]
5447pub unsafe extern "C" fn ysticky_index_from_index(
5448 branch: *const Branch,
5449 txn: *mut Transaction,
5450 index: u32,
5451 assoc: i8,
5452) -> *mut YStickyIndex {
5453 assert!(!branch.is_null());
5454 assert!(!txn.is_null());
5455
5456 let branch = BranchPtr::from_raw_branch(branch);
5457 let txn = txn.as_mut().unwrap();
5458 let index = index as u32;
5459 let assoc = if assoc >= 0 {
5460 Assoc::After
5461 } else {
5462 Assoc::Before
5463 };
5464
5465 if let Some(txn) = txn.as_mut() {
5466 if let Some(pos) = StickyIndex::at(txn, branch, index, assoc) {
5467 Box::into_raw(Box::new(YStickyIndex(pos)))
5468 } else {
5469 null_mut()
5470 }
5471 } else {
5472 panic!("ysticky_index_from_index requires a read-write transaction");
5473 }
5474}
5475
5476#[no_mangle]
5479pub unsafe extern "C" fn ysticky_index_encode(
5480 pos: *const YStickyIndex,
5481 len: *mut u32,
5482) -> *mut c_char {
5483 let pos = pos.as_ref().unwrap();
5484 let binary = pos.0.encode_v1().into_boxed_slice();
5485 *len = binary.len() as u32;
5486 Box::into_raw(binary) as *mut c_char
5487}
5488
5489#[no_mangle]
5492pub unsafe extern "C" fn ysticky_index_decode(
5493 binary: *const c_char,
5494 len: u32,
5495) -> *mut YStickyIndex {
5496 let slice = std::slice::from_raw_parts(binary as *const u8, len as usize);
5497 if let Ok(pos) = StickyIndex::decode_v1(slice) {
5498 Box::into_raw(Box::new(YStickyIndex(pos)))
5499 } else {
5500 null_mut()
5501 }
5502}
5503
5504#[no_mangle]
5508pub unsafe extern "C" fn ysticky_index_to_json(pos: *const YStickyIndex) -> *mut c_char {
5509 let pos = pos.as_ref().unwrap();
5510 let json = match serde_json::to_string(&pos.0) {
5511 Ok(json) => json,
5512 Err(_) => return null_mut(),
5513 };
5514 CString::new(json).unwrap().into_raw()
5515}
5516
5517#[no_mangle]
5526pub unsafe extern "C" fn ysticky_index_from_json(json: *const c_char) -> *mut YStickyIndex {
5527 let cstr = CStr::from_ptr(json);
5528 let json = match cstr.to_str() {
5529 Ok(json) => json,
5530 Err(_) => return null_mut(),
5531 };
5532 match serde_json::from_str(json) {
5533 Ok(pos) => Box::into_raw(Box::new(YStickyIndex(pos))),
5534 Err(_) => null_mut(),
5535 }
5536}
5537
5538#[no_mangle]
5544pub unsafe extern "C" fn ysticky_index_read(
5545 pos: *const YStickyIndex,
5546 txn: *const Transaction,
5547 out_branch: *mut *mut Branch,
5548 out_index: *mut u32,
5549) {
5550 let pos = pos.as_ref().unwrap();
5551 let txn = txn.as_ref().unwrap();
5552
5553 if let Some(abs) = pos.0.get_offset(txn) {
5554 *out_branch = abs.branch.as_ref() as *const Branch as *mut Branch;
5555 *out_index = abs.index as u32;
5556 }
5557}
5558
5559pub type Weak = LinkSource;
5560
5561#[no_mangle]
5562pub unsafe extern "C" fn yweak_destroy(weak: *const Weak) {
5563 drop(Arc::from_raw(weak));
5564}
5565
5566#[no_mangle]
5567pub unsafe extern "C" fn yweak_deref(
5568 map_link: *const Branch,
5569 txn: *const Transaction,
5570) -> *mut YOutput {
5571 assert!(!map_link.is_null());
5572 assert!(!txn.is_null());
5573
5574 let txn = txn.as_ref().unwrap();
5575 let weak: WeakRef<MapRef> = WeakRef::from_raw_branch(map_link);
5576 if let Some(value) = weak.try_deref_value(txn) {
5577 Box::into_raw(Box::new(YOutput::from(value)))
5578 } else {
5579 null_mut()
5580 }
5581}
5582
5583#[no_mangle]
5584pub unsafe extern "C" fn yweak_read(
5585 text_link: *const Branch,
5586 txn: *const Transaction,
5587 out_branch: *mut *mut Branch,
5588 out_start_index: *mut u32,
5589 out_end_index: *mut u32,
5590) {
5591 assert!(!text_link.is_null());
5592 assert!(!txn.is_null());
5593
5594 let txn = txn.as_ref().unwrap();
5595 let weak: WeakRef<BranchPtr> = WeakRef::from_raw_branch(text_link);
5596 if let Some(id) = weak.start_id() {
5597 let start = StickyIndex::from_id(*id, Assoc::After);
5599 assert!(weak.end_id() != None);
5600 let end = StickyIndex::from_id(*weak.end_id().unwrap(), Assoc::After);
5601 if let Some(start_pos) = start.get_offset(txn) {
5602 *out_branch = start_pos.branch.as_ref() as *const Branch as *mut Branch;
5603 *out_start_index = start_pos.index as u32;
5604 if let Some(end_pos) = end.get_offset(txn) {
5605 assert!(*out_branch == end_pos.branch.as_ref() as *const Branch as *mut Branch);
5606 *out_end_index = end_pos.index as u32;
5607 }
5608 }
5609 } else {
5610 assert!(weak.end_id() == None); *out_start_index = 0; *out_end_index = 0; }
5615}
5616
5617#[no_mangle]
5618pub unsafe extern "C" fn yweak_iter(
5619 array_link: *const Branch,
5620 txn: *const Transaction,
5621) -> *mut WeakIter {
5622 assert!(!array_link.is_null());
5623 assert!(!txn.is_null());
5624
5625 let txn = txn.as_ref().unwrap();
5626 let weak: WeakRef<ArrayRef> = WeakRef::from_raw_branch(array_link);
5627 let iter: NativeUnquote<'static, Transaction> = std::mem::transmute(weak.unquote(txn));
5628
5629 Box::into_raw(Box::new(WeakIter(iter)))
5630}
5631
5632#[no_mangle]
5633pub unsafe extern "C" fn yweak_iter_destroy(iter: *mut WeakIter) {
5634 drop(Box::from_raw(iter))
5635}
5636
5637#[no_mangle]
5638pub unsafe extern "C" fn yweak_iter_next(iter: *mut WeakIter) -> *mut YOutput {
5639 assert!(!iter.is_null());
5640 let iter = iter.as_mut().unwrap();
5641
5642 if let Some(value) = iter.0.next() {
5643 Box::into_raw(Box::new(YOutput::from(value)))
5644 } else {
5645 null_mut()
5646 }
5647}
5648
5649#[no_mangle]
5650pub unsafe extern "C" fn yweak_string(
5651 text_link: *const Branch,
5652 txn: *const Transaction,
5653) -> *mut c_char {
5654 assert!(!text_link.is_null());
5655 assert!(!txn.is_null());
5656
5657 let txn = txn.as_ref().unwrap();
5658 let weak: WeakRef<TextRef> = WeakRef::from_raw_branch(text_link);
5659
5660 let str = weak.get_string(txn);
5661 CString::new(str).unwrap().into_raw()
5662}
5663
5664#[no_mangle]
5665pub unsafe extern "C" fn yweak_xml_string(
5666 xml_text_link: *const Branch,
5667 txn: *const Transaction,
5668) -> *mut c_char {
5669 assert!(!xml_text_link.is_null());
5670 assert!(!txn.is_null());
5671
5672 let txn = txn.as_ref().unwrap();
5673 let weak: WeakRef<XmlTextRef> = WeakRef::from_raw_branch(xml_text_link);
5674
5675 let str = weak.get_string(txn);
5676 CString::new(str).unwrap().into_raw()
5677}
5678
5679#[no_mangle]
5684pub unsafe extern "C" fn yweak_observe(
5685 weak: *const Branch,
5686 state: *mut c_void,
5687 cb: extern "C" fn(*mut c_void, *const YWeakLinkEvent),
5688) -> *mut Subscription {
5689 assert!(!weak.is_null());
5690
5691 let state = CallbackState::new(state);
5692 let txt: WeakRef<BranchPtr> = WeakRef::from_raw_branch(weak);
5693 let subscription = txt.observe(move |txn, e| {
5694 let e = YWeakLinkEvent::new(e, txn);
5695 cb(state.0, &e as *const YWeakLinkEvent);
5696 });
5697 Box::into_raw(Box::new(subscription))
5698}
5699
5700#[no_mangle]
5701pub unsafe extern "C" fn ymap_link(
5702 map: *const Branch,
5703 txn: *const Transaction,
5704 key: *const c_char,
5705) -> *const Weak {
5706 assert!(!map.is_null());
5707 assert!(!txn.is_null());
5708
5709 let txn = txn.as_ref().unwrap();
5710 let map = MapRef::from_raw_branch(map);
5711 let key = CStr::from_ptr(key).to_str().unwrap();
5712 if let Some(weak) = map.link(txn, key) {
5713 let source = weak.source();
5714 Arc::into_raw(source.clone())
5715 } else {
5716 null()
5717 }
5718}
5719
5720#[no_mangle]
5721pub unsafe extern "C" fn ytext_quote(
5722 text: *const Branch,
5723 txn: *mut Transaction,
5724 start_index: *mut u32,
5725 end_index: *mut u32,
5726 start_exclusive: i8,
5727 end_exclusive: i8,
5728) -> *const Weak {
5729 assert!(!text.is_null());
5730 assert!(!txn.is_null());
5731
5732 let text = TextRef::from_raw_branch(text);
5733 let txn = txn.as_mut().unwrap();
5734 let txn = txn
5735 .as_mut()
5736 .expect("provided transaction was not writeable");
5737
5738 let start_index = start_index.as_ref().cloned();
5739 let end_index = end_index.as_ref().cloned();
5740 let range = ExplicitRange {
5741 start_index,
5742 end_index,
5743 start_exclusive,
5744 end_exclusive,
5745 };
5746 if let Ok(weak) = text.quote(txn, range) {
5747 let source = weak.source();
5748 Arc::into_raw(source.clone())
5749 } else {
5750 null()
5751 }
5752}
5753
5754#[no_mangle]
5755pub unsafe extern "C" fn yarray_quote(
5756 array: *const Branch,
5757 txn: *mut Transaction,
5758 start_index: *mut u32,
5759 end_index: *mut u32,
5760 start_exclusive: i8,
5761 end_exclusive: i8,
5762) -> *const Weak {
5763 assert!(!array.is_null());
5764 assert!(!txn.is_null());
5765
5766 let array = ArrayRef::from_raw_branch(array);
5767 let txn = txn.as_mut().unwrap();
5768 let txn = txn
5769 .as_mut()
5770 .expect("provided transaction was not writeable");
5771
5772 let start_index = start_index.as_ref().cloned();
5773 let end_index = end_index.as_ref().cloned();
5774 let range = ExplicitRange {
5775 start_index,
5776 end_index,
5777 start_exclusive,
5778 end_exclusive,
5779 };
5780 if let Ok(weak) = array.quote(txn, range) {
5781 let source = weak.source();
5782 Arc::into_raw(source.clone())
5783 } else {
5784 null()
5785 }
5786}
5787
5788struct ExplicitRange {
5789 start_index: Option<u32>,
5790 end_index: Option<u32>,
5791 start_exclusive: i8,
5792 end_exclusive: i8,
5793}
5794
5795impl RangeBounds<u32> for ExplicitRange {
5796 fn start_bound(&self) -> Bound<&u32> {
5797 match (&self.start_index, self.start_exclusive) {
5798 (None, _) => Bound::Unbounded,
5799 (Some(i), 0) => Bound::Included(i),
5800 (Some(i), _) => Bound::Excluded(i),
5801 }
5802 }
5803
5804 fn end_bound(&self) -> Bound<&u32> {
5805 match (&self.end_index, self.end_exclusive) {
5806 (None, _) => Bound::Unbounded,
5807 (Some(i), 0) => Bound::Included(i),
5808 (Some(i), _) => Bound::Excluded(i),
5809 }
5810 }
5811}
5812
5813#[repr(C)]
5821pub struct YBranchId {
5822 pub client_or_len: i64,
5825 pub variant: YBranchIdVariant,
5826}
5827
5828#[repr(C)]
5829pub union YBranchIdVariant {
5830 pub clock: u32,
5832 pub name: *const u8,
5837}
5838
5839#[no_mangle]
5842pub unsafe extern "C" fn ybranch_id(branch: *const Branch) -> YBranchId {
5843 let branch = branch.as_ref().unwrap();
5844 match branch.id() {
5845 BranchID::Nested(id) => YBranchId {
5846 client_or_len: id.client as i64,
5847 variant: YBranchIdVariant { clock: id.clock },
5848 },
5849 BranchID::Root(name) => {
5850 let len = -(name.len() as i64);
5851 YBranchId {
5852 client_or_len: len,
5853 variant: YBranchIdVariant {
5854 name: name.as_ptr(),
5855 },
5856 }
5857 }
5858 }
5859}
5860
5861#[no_mangle]
5867pub unsafe extern "C" fn ybranch_get(
5868 branch_id: *const YBranchId,
5869 txn: *mut Transaction,
5870) -> *mut Branch {
5871 let txn = txn.as_ref().unwrap();
5872 let branch_id = branch_id.as_ref().unwrap();
5873 let client_or_len = branch_id.client_or_len;
5874 let ptr = if client_or_len >= 0 {
5875 BranchID::get_nested(txn, &ID::new(client_or_len as u64, branch_id.variant.clock))
5876 } else {
5877 let name = std::slice::from_raw_parts(branch_id.variant.name, (-client_or_len) as usize);
5878 BranchID::get_root(txn, std::str::from_utf8_unchecked(name))
5879 };
5880
5881 match ptr {
5882 None => null_mut(),
5883 Some(branch_ptr) => branch_ptr.into_raw_branch(),
5884 }
5885}
5886
5887#[no_mangle]
5891pub unsafe extern "C" fn ybranch_alive(branch: *mut Branch) -> u8 {
5892 if branch.is_null() {
5893 Y_FALSE
5894 } else {
5895 let branch = BranchPtr::from_raw_branch(branch);
5896 if branch.is_deleted() {
5897 Y_FALSE
5898 } else {
5899 Y_TRUE
5900 }
5901 }
5902}
5903
5904#[no_mangle]
5911pub unsafe extern "C" fn ybranch_json(branch: *mut Branch, txn: *mut Transaction) -> *mut c_char {
5912 if branch.is_null() {
5913 std::ptr::null_mut()
5914 } else {
5915 let txn = txn.as_ref().unwrap();
5916 let branch_ref = BranchPtr::from_raw_branch(branch);
5917 let any = match branch_ref.type_ref() {
5918 TypeRef::Array => ArrayRef::from_raw_branch(branch).to_json(txn),
5919 TypeRef::Map => MapRef::from_raw_branch(branch).to_json(txn),
5920 TypeRef::Text => TextRef::from_raw_branch(branch).get_string(txn).into(),
5921 TypeRef::XmlElement(_) => XmlElementRef::from_raw_branch(branch)
5922 .get_string(txn)
5923 .into(),
5924 TypeRef::XmlFragment => XmlFragmentRef::from_raw_branch(branch)
5925 .get_string(txn)
5926 .into(),
5927 TypeRef::XmlText => XmlTextRef::from_raw_branch(branch).get_string(txn).into(),
5928 TypeRef::SubDoc | TypeRef::XmlHook | TypeRef::WeakLink(_) | TypeRef::Undefined => {
5929 return std::ptr::null_mut()
5930 }
5931 };
5932 let json = match serde_json::to_string(&any) {
5933 Ok(json) => json,
5934 Err(_) => return std::ptr::null_mut(),
5935 };
5936 CString::new(json).unwrap().into_raw()
5937 }
5938}