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