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 type Doc = yrs::Doc;
111
112pub type Branch = yrs::branch::Branch;
120
121pub type Subscription = yrs::Subscription;
125
126#[repr(transparent)]
128pub struct ArrayIter(NativeArrayIter<&'static Transaction, Transaction>);
129
130#[repr(transparent)]
132pub struct WeakIter(NativeUnquote<'static, Transaction>);
133
134#[repr(transparent)]
137pub struct MapIter(NativeMapIter<'static, &'static Transaction, Transaction>);
138
139#[repr(transparent)]
143pub struct Attributes(NativeAttributes<'static, &'static Transaction, Transaction>);
144
145#[repr(transparent)]
150pub struct TreeWalker(NativeTreeWalker<'static, &'static Transaction, Transaction>);
151
152#[repr(transparent)]
156pub struct Transaction(TransactionInner);
157
158#[repr(C)]
160pub struct JsonPathIter {
161 query: String,
162 json_path: Box<JsonPath<'static>>,
163 inner: NativeJsonPathIter<'static, Transaction>,
164}
165
166enum TransactionInner {
167 ReadOnly(yrs::Transaction<'static>),
168 ReadWrite(yrs::TransactionMut<'static>),
169}
170
171impl Transaction {
172 fn read_only(txn: yrs::Transaction) -> Self {
173 Transaction(TransactionInner::ReadOnly(unsafe {
174 std::mem::transmute(txn)
175 }))
176 }
177
178 fn read_write(txn: yrs::TransactionMut) -> Self {
179 Transaction(TransactionInner::ReadWrite(unsafe {
180 std::mem::transmute(txn)
181 }))
182 }
183
184 fn is_writeable(&self) -> bool {
185 match &self.0 {
186 TransactionInner::ReadOnly(_) => false,
187 TransactionInner::ReadWrite(_) => true,
188 }
189 }
190
191 fn as_mut(&mut self) -> Option<&mut yrs::TransactionMut<'static>> {
192 match &mut self.0 {
193 TransactionInner::ReadOnly(_) => None,
194 TransactionInner::ReadWrite(txn) => Some(txn),
195 }
196 }
197}
198
199impl ReadTxn for Transaction {
200 fn store(&self) -> &Store {
201 match &self.0 {
202 TransactionInner::ReadOnly(txn) => txn.store(),
203 TransactionInner::ReadWrite(txn) => txn.store(),
204 }
205 }
206}
207
208#[repr(C)]
211pub struct YMapEntry {
212 pub key: *const c_char,
214 pub value: *const YOutput,
217}
218
219impl YMapEntry {
220 fn new(key: &str, value: Box<YOutput>) -> Self {
221 let key = CString::new(key).unwrap().into_raw();
222 let value = Box::into_raw(value) as *const YOutput;
223 YMapEntry { key, value }
224 }
225}
226
227impl Drop for YMapEntry {
228 fn drop(&mut self) {
229 unsafe {
230 drop(CString::from_raw(self.key as *mut c_char));
231 drop(Box::from_raw(self.value as *mut YOutput));
232 }
233 }
234}
235
236#[repr(C)]
239pub struct YXmlAttr {
240 pub name: *const c_char,
241 pub value: *const YOutput,
242}
243
244impl Drop for YXmlAttr {
245 fn drop(&mut self) {
246 unsafe {
247 drop(CString::from_raw(self.name as *mut _));
248 if (!self.value.is_null()) {
249 drop(Box::from_raw(self.value as *mut YOutput));
250 }
251 }
252 }
253}
254
255#[repr(C)]
257pub struct YOptions {
258 pub id: u64,
265
266 pub guid: *const c_char,
269
270 pub collection_id: *const c_char,
273
274 pub flags: u8,
282}
283
284pub const Y_OFFSET_BYTES: u8 = 0;
287
288pub const Y_OFFSET_UTF16: u8 = 1;
291
292pub const Y_SKIP_GC: u8 = 1 << 1;
295
296pub const Y_AUTO_LOAD: u8 = 1 << 2;
299
300pub const Y_SHOULD_LOAD: u8 = 1 << 3;
302
303pub const Y_CLEANUP_FMT: u8 = 1 << 4;
309
310impl Into<Options> for YOptions {
311 fn into(self) -> Options {
312 let mut offset_kind = OffsetKind::Bytes;
313 if self.flags & Y_OFFSET_UTF16 != 0 {
314 offset_kind = OffsetKind::Utf16;
315 }
316 let skip_gc = self.flags & Y_SKIP_GC != 0;
317 let auto_load = self.flags & Y_AUTO_LOAD != 0;
318 let should_load = self.flags & Y_SHOULD_LOAD != 0;
319 let cleanup_formatting = self.flags & Y_CLEANUP_FMT != 0;
320 let guid = if self.guid.is_null() {
321 uuid_v4()
322 } else {
323 let c_str = unsafe { CStr::from_ptr(self.guid) };
324 let str = c_str.to_str().unwrap();
325 str.into()
326 };
327 let collection_id = if self.collection_id.is_null() {
328 None
329 } else {
330 let c_str = unsafe { CStr::from_ptr(self.collection_id) };
331 let str = Arc::from(c_str.to_str().unwrap());
332 Some(str)
333 };
334 Options {
335 client_id: ClientID::new(self.id),
336 guid,
337 collection_id,
338 skip_gc,
339 auto_load,
340 should_load,
341 offset_kind,
342 cleanup_formatting,
343 }
344 }
345}
346
347impl From<Options> for YOptions {
348 fn from(o: Options) -> Self {
349 let mut flags = 0;
350 if o.offset_kind == OffsetKind::Utf16 {
351 flags |= Y_OFFSET_UTF16;
352 }
353 if o.skip_gc {
354 flags |= Y_SKIP_GC;
355 }
356 if o.auto_load {
357 flags |= Y_AUTO_LOAD;
358 }
359 if o.should_load {
360 flags |= Y_SHOULD_LOAD;
361 }
362 if o.cleanup_formatting {
363 flags |= Y_CLEANUP_FMT;
364 }
365
366 YOptions {
367 id: o.client_id.get(),
368 guid: CString::new(o.guid.as_ref()).unwrap().into_raw(),
369 collection_id: if let Some(collection_id) = o.collection_id {
370 CString::new(collection_id.to_string()).unwrap().into_raw()
371 } else {
372 null_mut()
373 },
374 flags,
375 }
376 }
377}
378
379#[no_mangle]
381pub unsafe extern "C" fn yoptions() -> YOptions {
382 Options::default().into()
383}
384
385#[no_mangle]
387pub unsafe extern "C" fn ydoc_destroy(value: *mut Doc) {
388 if !value.is_null() {
389 drop(Box::from_raw(value));
390 }
391}
392
393#[no_mangle]
395pub unsafe extern "C" fn ymap_entry_destroy(value: *mut YMapEntry) {
396 if !value.is_null() {
397 drop(Box::from_raw(value));
398 }
399}
400
401#[no_mangle]
403pub unsafe extern "C" fn yxmlattr_destroy(attr: *mut YXmlAttr) {
404 if !attr.is_null() {
405 drop(Box::from_raw(attr));
406 }
407}
408
409#[no_mangle]
412pub unsafe extern "C" fn ystring_destroy(str: *mut c_char) {
413 if !str.is_null() {
414 drop(CString::from_raw(str));
415 }
416}
417
418#[no_mangle]
423pub unsafe extern "C" fn ybinary_destroy(ptr: *mut c_char, len: u32) {
424 if !ptr.is_null() {
425 drop(Vec::from_raw_parts(ptr, len as usize, len as usize));
426 }
427}
428
429#[no_mangle]
433pub extern "C" fn ydoc_new() -> *mut Doc {
434 Box::into_raw(Box::new(Doc::new()))
435}
436
437#[no_mangle]
443pub unsafe extern "C" fn ydoc_clone(doc: *mut Doc) -> *mut Doc {
444 let doc = doc.as_mut().unwrap();
445 Box::into_raw(Box::new(doc.clone()))
446}
447
448#[no_mangle]
452pub extern "C" fn ydoc_new_with_options(options: YOptions) -> *mut Doc {
453 Box::into_raw(Box::new(Doc::with_options(options.into())))
454}
455
456#[no_mangle]
458pub unsafe extern "C" fn ydoc_id(doc: *mut Doc) -> u64 {
459 let doc = doc.as_ref().unwrap();
460 doc.client_id().get()
461}
462
463#[no_mangle]
467pub unsafe extern "C" fn ydoc_guid(doc: *mut Doc) -> *mut c_char {
468 let doc = doc.as_ref().unwrap();
469 let uid = doc.guid();
470 CString::new(uid.as_ref()).unwrap().into_raw()
471}
472
473#[no_mangle]
478pub unsafe extern "C" fn ydoc_collection_id(doc: *mut Doc) -> *mut c_char {
479 let doc = doc.as_ref().unwrap();
480 if let Some(cid) = doc.collection_id() {
481 CString::new(cid.as_ref()).unwrap().into_raw()
482 } else {
483 null_mut()
484 }
485}
486
487#[no_mangle]
490pub unsafe extern "C" fn ydoc_should_load(doc: *mut Doc) -> u8 {
491 let doc = doc.as_ref().unwrap();
492 doc.should_load() as u8
493}
494
495#[no_mangle]
498pub unsafe extern "C" fn ydoc_auto_load(doc: *mut Doc) -> u8 {
499 let doc = doc.as_ref().unwrap();
500 doc.auto_load() as u8
501}
502
503#[repr(transparent)]
504struct CallbackState(*mut c_void);
505
506unsafe impl Send for CallbackState {}
507unsafe impl Sync for CallbackState {}
508
509impl CallbackState {
510 #[inline]
511 fn new(state: *mut c_void) -> Self {
512 CallbackState(state)
513 }
514}
515
516#[no_mangle]
517pub unsafe extern "C" fn ydoc_observe_updates_v1(
518 doc: *mut Doc,
519 state: *mut c_void,
520 cb: extern "C" fn(*mut c_void, u32, *const c_char),
521) -> *mut Subscription {
522 let state = CallbackState::new(state);
523 let doc = doc.as_ref().unwrap();
524 let subscription = doc
525 .observe_update_v1(move |_, e| {
526 let bytes = &e.update;
527 let len = bytes.len() as u32;
528 cb(state.0, len, bytes.as_ptr() as *const c_char)
529 })
530 .unwrap();
531 Box::into_raw(Box::new(subscription))
532}
533
534#[no_mangle]
535pub unsafe extern "C" fn ydoc_observe_updates_v2(
536 doc: *mut Doc,
537 state: *mut c_void,
538 cb: extern "C" fn(*mut c_void, u32, *const c_char),
539) -> *mut Subscription {
540 let state = CallbackState::new(state);
541 let doc = doc.as_ref().unwrap();
542 let subscription = doc
543 .observe_update_v2(move |_, e| {
544 let bytes = &e.update;
545 let len = bytes.len() as u32;
546 cb(state.0, len, bytes.as_ptr() as *const c_char)
547 })
548 .unwrap();
549 Box::into_raw(Box::new(subscription))
550}
551
552#[no_mangle]
553pub unsafe extern "C" fn ydoc_observe_after_transaction(
554 doc: *mut Doc,
555 state: *mut c_void,
556 cb: extern "C" fn(*mut c_void, *mut YAfterTransactionEvent),
557) -> *mut Subscription {
558 let state = CallbackState::new(state);
559 let doc = doc.as_ref().unwrap();
560 let subscription = doc
561 .observe_transaction_cleanup(move |_, e| {
562 let mut event = YAfterTransactionEvent::new(e);
563 cb(state.0, (&mut event) as *mut _);
564 })
565 .unwrap();
566 Box::into_raw(Box::new(subscription))
567}
568
569#[no_mangle]
570pub unsafe extern "C" fn ydoc_observe_subdocs(
571 doc: *mut Doc,
572 state: *mut c_void,
573 cb: extern "C" fn(*mut c_void, *mut YSubdocsEvent),
574) -> *mut Subscription {
575 let state = CallbackState::new(state);
576 let doc = doc.as_mut().unwrap();
577 let subscription = doc
578 .observe_subdocs(move |_, e| {
579 let mut event = YSubdocsEvent::new(e);
580 cb(state.0, (&mut event) as *mut _);
581 })
582 .unwrap();
583 Box::into_raw(Box::new(subscription))
584}
585
586#[no_mangle]
587pub unsafe extern "C" fn ydoc_observe_clear(
588 doc: *mut Doc,
589 state: *mut c_void,
590 cb: extern "C" fn(*mut c_void, *mut Doc),
591) -> *mut Subscription {
592 let state = CallbackState::new(state);
593 let doc = doc.as_mut().unwrap();
594 let subscription = doc
595 .observe_destroy(move |_, e| cb(state.0, e as *const Doc as *mut _))
596 .unwrap();
597 Box::into_raw(Box::new(subscription))
598}
599
600#[no_mangle]
602pub unsafe extern "C" fn ydoc_load(doc: *mut Doc, parent_txn: *mut Transaction) {
603 let doc = doc.as_ref().unwrap();
604 let txn = parent_txn.as_mut().unwrap();
605 if let Some(txn) = txn.as_mut() {
606 doc.load(txn)
607 } else {
608 panic!("ydoc_load: passed read-only parent transaction, where read-write one was expected")
609 }
610}
611
612#[no_mangle]
615pub unsafe extern "C" fn ydoc_clear(doc: *mut Doc, parent_txn: *mut Transaction) {
616 let doc = doc.as_mut().unwrap();
617 let txn = parent_txn.as_mut();
618 let txn = txn.and_then(|tx| tx.as_mut());
619 doc.destroy(txn);
620}
621
622#[no_mangle]
629pub unsafe extern "C" fn ydoc_read_transaction(doc: *mut Doc) -> *mut Transaction {
630 assert!(!doc.is_null());
631
632 let doc = doc.as_mut().unwrap();
633 if let Ok(txn) = doc.try_transact() {
634 Box::into_raw(Box::new(Transaction::read_only(txn)))
635 } else {
636 null_mut()
637 }
638}
639
640#[no_mangle]
652pub unsafe extern "C" fn ydoc_write_transaction(
653 doc: *mut Doc,
654 origin_len: u32,
655 origin: *const c_char,
656) -> *mut Transaction {
657 assert!(!doc.is_null());
658
659 let doc = doc.as_mut().unwrap();
660 if origin_len == 0 {
661 if let Ok(txn) = doc.try_transact_mut() {
662 Box::into_raw(Box::new(Transaction::read_write(txn)))
663 } else {
664 null_mut()
665 }
666 } else {
667 let origin = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
668 if let Ok(txn) = doc.try_transact_mut_with(origin) {
669 Box::into_raw(Box::new(Transaction::read_write(txn)))
670 } else {
671 null_mut()
672 }
673 }
674}
675
676#[no_mangle]
678pub unsafe extern "C" fn ytransaction_subdocs(
679 txn: *mut Transaction,
680 len: *mut u32,
681) -> *mut *mut Doc {
682 let txn = txn.as_ref().unwrap();
683 let subdocs: Vec<_> = txn
684 .subdocs()
685 .map(|doc| doc as *const Doc as *mut Doc)
686 .collect();
687 let out = subdocs.into_boxed_slice();
688 *len = out.len() as u32;
689 Box::into_raw(out) as *mut _
690}
691
692#[no_mangle]
696pub unsafe extern "C" fn ytransaction_commit(txn: *mut Transaction) {
697 assert!(!txn.is_null());
698 drop(Box::from_raw(txn)); }
700
701#[no_mangle]
705pub unsafe extern "C" fn ytransaction_force_gc(txn: *mut Transaction) {
706 assert!(!txn.is_null());
707 let txn = txn.as_mut().unwrap();
708 let txn = txn.as_mut().unwrap();
709 txn.gc(None);
710}
711
712#[no_mangle]
715pub unsafe extern "C" fn ytransaction_writeable(txn: *mut Transaction) -> u8 {
716 assert!(!txn.is_null());
717 if txn.as_ref().unwrap().is_writeable() {
718 1
719 } else {
720 0
721 }
722}
723
724#[no_mangle]
745pub unsafe extern "C" fn ytransaction_json_path(
746 txn: *mut Transaction,
747 json_path: *const c_char,
748) -> *mut JsonPathIter {
749 assert!(!txn.is_null());
750 let txn = txn.as_ref().unwrap();
751
752 let query: String = CStr::from_ptr(json_path).to_str().unwrap().into();
754 let json_path: &'static str = unsafe { std::mem::transmute(query.as_str()) };
756 let json_path = match JsonPath::parse(json_path) {
757 Ok(query) => Box::new(query),
758 Err(_) => return null_mut(),
759 };
760 let json_path_ref: &'static JsonPath = unsafe { std::mem::transmute(json_path.as_ref()) };
762 let inner = txn.json_path(json_path_ref);
763 let iter = Box::new(JsonPathIter {
764 query,
765 json_path,
766 inner,
767 });
768 Box::into_raw(iter)
769}
770
771#[no_mangle]
773pub unsafe extern "C" fn yjson_path_iter_next(iter: *mut JsonPathIter) -> *mut YOutput {
774 assert!(!iter.is_null());
775 let iter = iter.as_mut().unwrap();
776 if let Some(value) = iter.inner.next() {
777 let youtput = YOutput::from(value);
778 Box::into_raw(Box::new(youtput))
779 } else {
780 null_mut()
781 }
782}
783
784#[no_mangle]
786pub unsafe extern "C" fn yjson_path_iter_destroy(iter: *mut JsonPathIter) {
787 if !iter.is_null() {
788 drop(Box::from_raw(iter));
789 }
790}
791
792#[no_mangle]
798pub unsafe extern "C" fn ytype_get(txn: *mut Transaction, name: *const c_char) -> *mut Branch {
799 assert!(!txn.is_null());
800 assert!(!name.is_null());
801
802 let name = CStr::from_ptr(name).to_str().unwrap();
803 if let Some(txt) = txn.as_mut().unwrap().get_text(name) {
806 txt.into_raw_branch()
807 } else {
808 null_mut()
809 }
810}
811
812#[no_mangle]
816pub unsafe extern "C" fn ytext(doc: *mut Doc, name: *const c_char) -> *mut Branch {
817 assert!(!doc.is_null());
818 assert!(!name.is_null());
819
820 let name = CStr::from_ptr(name).to_str().unwrap();
821 let txt = doc.as_mut().unwrap().get_or_insert_text(name);
822 txt.into_raw_branch()
823}
824
825#[no_mangle]
831pub unsafe extern "C" fn yarray(doc: *mut Doc, name: *const c_char) -> *mut Branch {
832 assert!(!doc.is_null());
833 assert!(!name.is_null());
834
835 let name = CStr::from_ptr(name).to_str().unwrap();
836 doc.as_mut()
837 .unwrap()
838 .get_or_insert_array(name)
839 .into_raw_branch()
840}
841
842#[no_mangle]
848pub unsafe extern "C" fn ymap(doc: *mut Doc, name: *const c_char) -> *mut Branch {
849 assert!(!doc.is_null());
850 assert!(!name.is_null());
851
852 let name = CStr::from_ptr(name).to_str().unwrap();
853 doc.as_mut()
854 .unwrap()
855 .get_or_insert_map(name)
856 .into_raw_branch()
857}
858
859#[no_mangle]
863pub unsafe extern "C" fn yxmlfragment(doc: *mut Doc, name: *const c_char) -> *mut Branch {
864 assert!(!doc.is_null());
865 assert!(!name.is_null());
866
867 let name = CStr::from_ptr(name).to_str().unwrap();
868 doc.as_mut()
869 .unwrap()
870 .get_or_insert_xml_fragment(name)
871 .into_raw_branch()
872}
873
874#[no_mangle]
884pub unsafe extern "C" fn ytransaction_state_vector_v1(
885 txn: *const Transaction,
886 len: *mut u32,
887) -> *mut c_char {
888 assert!(!txn.is_null());
889
890 let txn = txn.as_ref().unwrap();
891 let state_vector = txn.state_vector();
892 let binary = state_vector.encode_v1().into_boxed_slice();
893
894 *len = binary.len() as u32;
895 Box::into_raw(binary) as *mut c_char
896}
897
898#[no_mangle]
913pub unsafe extern "C" fn ytransaction_state_diff_v1(
914 txn: *const Transaction,
915 sv: *const c_char,
916 sv_len: u32,
917 len: *mut u32,
918) -> *mut c_char {
919 assert!(!txn.is_null());
920
921 let txn = txn.as_ref().unwrap();
922 let sv = {
923 if sv.is_null() {
924 StateVector::default()
925 } else {
926 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
927 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
928 sv
929 } else {
930 return null_mut();
931 }
932 }
933 };
934
935 let mut encoder = EncoderV1::new();
936 txn.encode_diff(&sv, &mut encoder);
937 let binary = encoder.to_vec().into_boxed_slice();
938 *len = binary.len() as u32;
939 Box::into_raw(binary) as *mut c_char
940}
941
942#[no_mangle]
957pub unsafe extern "C" fn ytransaction_state_diff_v2(
958 txn: *const Transaction,
959 sv: *const c_char,
960 sv_len: u32,
961 len: *mut u32,
962) -> *mut c_char {
963 assert!(!txn.is_null());
964
965 let txn = txn.as_ref().unwrap();
966 let sv = {
967 if sv.is_null() {
968 StateVector::default()
969 } else {
970 let sv_slice = std::slice::from_raw_parts(sv as *const u8, sv_len as usize);
971 if let Ok(sv) = StateVector::decode_v1(sv_slice) {
972 sv
973 } else {
974 return null_mut();
975 }
976 }
977 };
978
979 let mut encoder = EncoderV2::new();
980 txn.encode_diff(&sv, &mut encoder);
981 let binary = encoder.to_vec().into_boxed_slice();
982 *len = binary.len() as u32;
983 Box::into_raw(binary) as *mut c_char
984}
985
986#[no_mangle]
990pub unsafe extern "C" fn ytransaction_snapshot(
991 txn: *const Transaction,
992 len: *mut u32,
993) -> *mut c_char {
994 assert!(!txn.is_null());
995 let txn = txn.as_ref().unwrap();
996 let binary = txn.snapshot().encode_v1().into_boxed_slice();
997
998 *len = binary.len() as u32;
999 Box::into_raw(binary) as *mut c_char
1000}
1001
1002#[no_mangle]
1011pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v1(
1012 txn: *const Transaction,
1013 snapshot: *const c_char,
1014 snapshot_len: u32,
1015 len: *mut u32,
1016) -> *mut c_char {
1017 assert!(!txn.is_null());
1018 let txn = txn.as_ref().unwrap();
1019 let snapshot = {
1020 let len = snapshot_len as usize;
1021 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
1022 Snapshot::decode_v1(&data).unwrap()
1023 };
1024 let mut encoder = EncoderV1::new();
1025 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
1026 Err(_) => null_mut(),
1027 Ok(_) => {
1028 let binary = encoder.to_vec().into_boxed_slice();
1029 *len = binary.len() as u32;
1030 Box::into_raw(binary) as *mut c_char
1031 }
1032 }
1033}
1034
1035#[no_mangle]
1044pub unsafe extern "C" fn ytransaction_encode_state_from_snapshot_v2(
1045 txn: *const Transaction,
1046 snapshot: *const c_char,
1047 snapshot_len: u32,
1048 len: *mut u32,
1049) -> *mut c_char {
1050 assert!(!txn.is_null());
1051 let txn = txn.as_ref().unwrap();
1052 let snapshot = {
1053 let len = snapshot_len as usize;
1054 let data = std::slice::from_raw_parts(snapshot as *mut u8, len);
1055 Snapshot::decode_v1(&data).unwrap()
1056 };
1057 let mut encoder = EncoderV2::new();
1058 match txn.encode_state_from_snapshot(&snapshot, &mut encoder) {
1059 Err(_) => null_mut(),
1060 Ok(_) => {
1061 let binary = encoder.to_vec().into_boxed_slice();
1062 *len = binary.len() as u32;
1063 Box::into_raw(binary) as *mut c_char
1064 }
1065 }
1066}
1067
1068#[no_mangle]
1074pub unsafe extern "C" fn ytransaction_pending_ds(txn: *const Transaction) -> *mut YIdSet {
1075 let txn = txn.as_ref().unwrap();
1076 match txn.store().pending_ds() {
1077 None => null_mut(),
1078 Some(ds) => Box::into_raw(Box::new(YIdSet::new(ds))),
1079 }
1080}
1081
1082#[no_mangle]
1083pub unsafe extern "C" fn ydelete_set_destroy(ds: *mut YIdSet) {
1084 if ds.is_null() {
1085 return;
1086 }
1087 drop(Box::from_raw(ds))
1088}
1089
1090#[no_mangle]
1099pub unsafe extern "C" fn ytransaction_pending_update(
1100 txn: *const Transaction,
1101) -> *mut YPendingUpdate {
1102 let txn = txn.as_ref().unwrap();
1103 match txn.store().pending_update() {
1104 None => null_mut(),
1105 Some(u) => {
1106 let binary = u.update.encode_v1().into_boxed_slice();
1107 let update_len = binary.len() as u32;
1108 let missing = YStateVector::new(&u.missing);
1109 let update = YPendingUpdate {
1110 missing,
1111 update_len,
1112 update_v1: Box::into_raw(binary) as *mut c_char,
1113 };
1114 Box::into_raw(Box::new(update))
1115 }
1116 }
1117}
1118
1119#[repr(C)]
1123pub struct YPendingUpdate {
1124 pub missing: YStateVector,
1127 pub update_v1: *mut c_char,
1129 pub update_len: u32,
1131}
1132
1133#[no_mangle]
1134pub unsafe extern "C" fn ypending_update_destroy(update: *mut YPendingUpdate) {
1135 if update.is_null() {
1136 return;
1137 }
1138 let update = Box::from_raw(update);
1139 drop(update.missing);
1140 ybinary_destroy(update.update_v1, update.update_len);
1141}
1142
1143#[no_mangle]
1147pub unsafe extern "C" fn yupdate_debug_v1(update: *const c_char, update_len: u32) -> *mut c_char {
1148 assert!(!update.is_null());
1149
1150 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1151 if let Ok(u) = Update::decode_v1(data) {
1152 let str = format!("{:#?}", u);
1153 CString::new(str).unwrap().into_raw()
1154 } else {
1155 null_mut()
1156 }
1157}
1158
1159#[no_mangle]
1163pub unsafe extern "C" fn yupdate_debug_v2(update: *const c_char, update_len: u32) -> *mut c_char {
1164 assert!(!update.is_null());
1165
1166 let data = std::slice::from_raw_parts(update as *const u8, update_len as usize);
1167 if let Ok(u) = Update::decode_v2(data) {
1168 let str = format!("{:#?}", u);
1169 CString::new(str).unwrap().into_raw()
1170 } else {
1171 null_mut()
1172 }
1173}
1174
1175#[no_mangle]
1189pub unsafe extern "C" fn ytransaction_apply(
1190 txn: *mut Transaction,
1191 diff: *const c_char,
1192 diff_len: u32,
1193) -> u8 {
1194 assert!(!txn.is_null());
1195 assert!(!diff.is_null());
1196
1197 let update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1198 let mut decoder = DecoderV1::from(update);
1199 match Update::decode(&mut decoder) {
1200 Ok(update) => {
1201 let txn = txn.as_mut().unwrap();
1202 let txn = txn
1203 .as_mut()
1204 .expect("provided transaction was not writeable");
1205 match txn.apply_update(update) {
1206 Ok(_) => 0,
1207 Err(e) => update_err_code(e),
1208 }
1209 }
1210 Err(e) => err_code(e),
1211 }
1212}
1213
1214#[no_mangle]
1228pub unsafe extern "C" fn ytransaction_apply_v2(
1229 txn: *mut Transaction,
1230 diff: *const c_char,
1231 diff_len: u32,
1232) -> u8 {
1233 assert!(!txn.is_null());
1234 assert!(!diff.is_null());
1235
1236 let mut update = std::slice::from_raw_parts(diff as *const u8, diff_len as usize);
1237 match Update::decode_v2(&mut update) {
1238 Ok(update) => {
1239 let txn = txn.as_mut().unwrap();
1240 let txn = txn
1241 .as_mut()
1242 .expect("provided transaction was not writeable");
1243 match txn.apply_update(update) {
1244 Ok(_) => 0,
1245 Err(e) => update_err_code(e),
1246 }
1247 }
1248 Err(e) => err_code(e),
1249 }
1250}
1251
1252pub const ERR_CODE_IO: u8 = 1;
1254
1255pub const ERR_CODE_VAR_INT: u8 = 2;
1257
1258pub const ERR_CODE_EOS: u8 = 3;
1260
1261pub const ERR_CODE_UNEXPECTED_VALUE: u8 = 4;
1263
1264pub const ERR_CODE_INVALID_JSON: u8 = 5;
1266
1267pub const ERR_CODE_OTHER: u8 = 6;
1269
1270pub const ERR_NOT_ENOUGH_MEMORY: u8 = 7;
1272
1273pub const ERR_TYPE_MISMATCH: u8 = 8;
1275
1276pub const ERR_CUSTOM: u8 = 9;
1278
1279pub const ERR_INVALID_PARENT: u8 = 9;
1281
1282fn err_code(e: Error) -> u8 {
1283 match e {
1284 Error::InvalidVarInt => ERR_CODE_VAR_INT,
1285 Error::EndOfBuffer(_) => ERR_CODE_EOS,
1286 Error::UnexpectedValue => ERR_CODE_UNEXPECTED_VALUE,
1287 Error::InvalidJSON(_) => ERR_CODE_INVALID_JSON,
1288 Error::NotEnoughMemory(_) => ERR_NOT_ENOUGH_MEMORY,
1289 Error::TypeMismatch(_) => ERR_TYPE_MISMATCH,
1290 Error::Custom(_) => ERR_CUSTOM,
1291 }
1292}
1293fn update_err_code(e: UpdateError) -> u8 {
1294 match e {
1295 UpdateError::InvalidParent(_, _) => ERR_INVALID_PARENT,
1296 }
1297}
1298
1299#[no_mangle]
1301pub unsafe extern "C" fn ytext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
1302 assert!(!txt.is_null());
1303 let txn = txn.as_ref().unwrap();
1304 let txt = TextRef::from_raw_branch(txt);
1305 txt.len(txn)
1306}
1307
1308#[no_mangle]
1312pub unsafe extern "C" fn ytext_string(txt: *const Branch, txn: *const Transaction) -> *mut c_char {
1313 assert!(!txt.is_null());
1314
1315 let txn = txn.as_ref().unwrap();
1316 let txt = TextRef::from_raw_branch(txt);
1317 let str = txt.get_string(txn);
1318 CString::new(str).unwrap().into_raw()
1319}
1320
1321#[no_mangle]
1332pub unsafe extern "C" fn ytext_insert(
1333 txt: *const Branch,
1334 txn: *mut Transaction,
1335 index: u32,
1336 value: *const c_char,
1337 attrs: *const YInput,
1338) {
1339 assert!(!txt.is_null());
1340 assert!(!txn.is_null());
1341 assert!(!value.is_null());
1342
1343 let chunk = CStr::from_ptr(value).to_str().unwrap();
1344 let txn = txn.as_mut().unwrap();
1345 let txn = txn
1346 .as_mut()
1347 .expect("provided transaction was not writeable");
1348 let txt = TextRef::from_raw_branch(txt);
1349 let index = index as u32;
1350 if attrs.is_null() {
1351 txt.insert(txn, index, chunk)
1352 } else {
1353 if let Some(attrs) = map_attrs(attrs.read().into()) {
1354 txt.insert_with_attributes(txn, index, chunk, attrs)
1355 } else {
1356 panic!("ytext_insert: passed attributes are not of map type")
1357 }
1358 }
1359}
1360
1361#[no_mangle]
1364pub unsafe extern "C" fn ytext_format(
1365 txt: *const Branch,
1366 txn: *mut Transaction,
1367 index: u32,
1368 len: u32,
1369 attrs: *const YInput,
1370) {
1371 assert!(!txt.is_null());
1372 assert!(!txn.is_null());
1373 assert!(!attrs.is_null());
1374
1375 if let Some(attrs) = map_attrs(attrs.read().into()) {
1376 let txt = TextRef::from_raw_branch(txt);
1377 let txn = txn.as_mut().unwrap();
1378 let txn = txn
1379 .as_mut()
1380 .expect("provided transaction was not writeable");
1381 let index = index as u32;
1382 let len = len as u32;
1383 txt.format(txn, index, len, attrs);
1384 } else {
1385 panic!("ytext_format: passed attributes are not of map type")
1386 }
1387}
1388
1389#[no_mangle]
1400pub unsafe extern "C" fn ytext_insert_embed(
1401 txt: *const Branch,
1402 txn: *mut Transaction,
1403 index: u32,
1404 content: *const YInput,
1405 attrs: *const YInput,
1406) {
1407 assert!(!txt.is_null());
1408 assert!(!txn.is_null());
1409 assert!(!content.is_null());
1410
1411 let txn = txn.as_mut().unwrap();
1412 let txn = txn
1413 .as_mut()
1414 .expect("provided transaction was not writeable");
1415 let txt = TextRef::from_raw_branch(txt);
1416 let index = index as u32;
1417 let content = content.read();
1418 if attrs.is_null() {
1419 txt.insert_embed(txn, index, content);
1420 } else {
1421 if let Some(attrs) = map_attrs(attrs.read().into()) {
1422 txt.insert_embed_with_attributes(txn, index, content, attrs);
1423 } else {
1424 panic!("ytext_insert_embed: passed attributes are not of map type")
1425 }
1426 }
1427}
1428
1429#[no_mangle]
1443pub unsafe extern "C" fn ytext_insert_delta(
1444 txt: *const Branch,
1445 txn: *mut Transaction,
1446 delta: *mut YDeltaIn,
1447 delta_len: u32,
1448) {
1449 let txt = TextRef::from_raw_branch(txt);
1450 let txn = txn.as_mut().unwrap();
1451 let txn = txn
1452 .as_mut()
1453 .expect("provided transaction was not writeable");
1454 let delta = std::slice::from_raw_parts(delta, delta_len as usize);
1455 let mut insert = Vec::with_capacity(delta.len());
1456 for chunk in delta {
1457 let d = chunk.as_input();
1458 insert.push(d);
1459 }
1460 txt.apply_delta(txn, insert);
1461}
1462
1463#[no_mangle]
1467pub unsafe extern "C" fn ydelta_input_retain(len: u32, attrs: *const YInput) -> YDeltaIn {
1468 YDeltaIn {
1469 tag: Y_EVENT_CHANGE_RETAIN,
1470 len,
1471 attributes: attrs,
1472 insert: null(),
1473 }
1474}
1475
1476#[no_mangle]
1479pub unsafe extern "C" fn ydelta_input_delete(len: u32) -> YDeltaIn {
1480 YDeltaIn {
1481 tag: Y_EVENT_CHANGE_DELETE,
1482 len,
1483 attributes: null(),
1484 insert: null(),
1485 }
1486}
1487
1488#[no_mangle]
1494pub unsafe extern "C" fn ydelta_input_insert(
1495 data: *const YInput,
1496 attrs: *const YInput,
1497) -> YDeltaIn {
1498 YDeltaIn {
1499 tag: Y_EVENT_CHANGE_ADD,
1500 len: 1,
1501 attributes: attrs,
1502 insert: data,
1503 }
1504}
1505
1506fn map_attrs(attrs: Any) -> Option<Attrs> {
1507 if let Any::Map(attrs) = attrs {
1508 let attrs = attrs
1509 .iter()
1510 .map(|(k, v)| (k.as_str().into(), v.clone()))
1511 .collect();
1512 Some(attrs)
1513 } else {
1514 None
1515 }
1516}
1517
1518#[no_mangle]
1527pub unsafe extern "C" fn ytext_remove_range(
1528 txt: *const Branch,
1529 txn: *mut Transaction,
1530 index: u32,
1531 length: u32,
1532) {
1533 assert!(!txt.is_null());
1534 assert!(!txn.is_null());
1535
1536 let txn = txn.as_mut().unwrap();
1537 let txn = txn
1538 .as_mut()
1539 .expect("provided transaction was not writeable");
1540 let txt = TextRef::from_raw_branch(txt);
1541 txt.remove_range(txn, index as u32, length as u32)
1542}
1543
1544#[no_mangle]
1546pub unsafe extern "C" fn yarray_len(array: *const Branch) -> u32 {
1547 assert!(!array.is_null());
1548
1549 let array = array.as_ref().unwrap();
1550 array.len() as u32
1551}
1552
1553#[no_mangle]
1558pub unsafe extern "C" fn yarray_get(
1559 array: *const Branch,
1560 txn: *const Transaction,
1561 index: u32,
1562) -> *mut YOutput {
1563 assert!(!array.is_null());
1564
1565 let array = ArrayRef::from_raw_branch(array);
1566 let txn = txn.as_ref().unwrap();
1567
1568 if let Some(val) = array.get(txn, index as u32) {
1569 Box::into_raw(Box::new(YOutput::from(val)))
1570 } else {
1571 std::ptr::null_mut()
1572 }
1573}
1574
1575#[no_mangle]
1586pub unsafe extern "C" fn yarray_get_json(
1587 array: *const Branch,
1588 txn: *const Transaction,
1589 index: u32,
1590) -> *mut c_char {
1591 assert!(!array.is_null());
1592
1593 let array = ArrayRef::from_raw_branch(array);
1594 let txn = txn.as_ref().unwrap();
1595
1596 if let Some(val) = array.get(txn, index as u32) {
1597 let any = val.to_json(txn);
1598 let json = match serde_json::to_string(&any) {
1599 Ok(json) => json,
1600 Err(_) => return std::ptr::null_mut(),
1601 };
1602 CString::new(json).unwrap().into_raw()
1603 } else {
1604 std::ptr::null_mut()
1605 }
1606}
1607
1608#[no_mangle]
1619pub unsafe extern "C" fn yarray_insert_range(
1620 array: *const Branch,
1621 txn: *mut Transaction,
1622 index: u32,
1623 items: *const YInput,
1624 items_len: u32,
1625) {
1626 assert!(!array.is_null());
1627 assert!(!txn.is_null());
1628 assert!(!items.is_null());
1629
1630 let array = ArrayRef::from_raw_branch(array);
1631 let txn = txn.as_mut().unwrap();
1632 let txn = txn
1633 .as_mut()
1634 .expect("provided transaction was not writeable");
1635
1636 let ptr = items;
1637 let mut i = 0;
1638 let mut j = index as u32;
1639 let len = items_len as isize;
1640 while i < len {
1641 let mut vec: Vec<Any> = Vec::default();
1642
1643 while i < len {
1645 let val = ptr.offset(i).read();
1646 if val.tag <= 0 {
1647 let any = val.into();
1648 vec.push(any);
1649 } else {
1650 break;
1651 }
1652 i += 1;
1653 }
1654
1655 if !vec.is_empty() {
1656 let len = vec.len() as u32;
1657 array.insert_range(txn, j, vec);
1658 j += len;
1659 } else {
1660 let val = ptr.offset(i).read();
1661 array.insert(txn, j, val);
1662 i += 1;
1663 j += 1;
1664 }
1665 }
1666}
1667
1668#[no_mangle]
1672pub unsafe extern "C" fn yarray_remove_range(
1673 array: *const Branch,
1674 txn: *mut Transaction,
1675 index: u32,
1676 len: u32,
1677) {
1678 assert!(!array.is_null());
1679 assert!(!txn.is_null());
1680
1681 let array = ArrayRef::from_raw_branch(array);
1682 let txn = txn.as_mut().unwrap();
1683 let txn = txn
1684 .as_mut()
1685 .expect("provided transaction was not writeable");
1686
1687 array.remove_range(txn, index as u32, len as u32)
1688}
1689
1690#[no_mangle]
1696pub unsafe extern "C" fn yarray_iter(
1697 array: *const Branch,
1698 txn: *mut Transaction,
1699) -> *mut ArrayIter {
1700 assert!(!array.is_null());
1701 assert!(!txn.is_null());
1702
1703 let txn = txn.as_ref().unwrap();
1704 let array = &ArrayRef::from_raw_branch(array) as *const ArrayRef;
1705 Box::into_raw(Box::new(ArrayIter(array.as_ref().unwrap().iter(txn))))
1706}
1707
1708#[no_mangle]
1710pub unsafe extern "C" fn yarray_iter_destroy(iter: *mut ArrayIter) {
1711 if !iter.is_null() {
1712 drop(Box::from_raw(iter))
1713 }
1714}
1715
1716#[no_mangle]
1721pub unsafe extern "C" fn yarray_iter_next(iterator: *mut ArrayIter) -> *mut YOutput {
1722 assert!(!iterator.is_null());
1723
1724 let iter = iterator.as_mut().unwrap();
1725 if let Some(v) = iter.0.next() {
1726 let out = YOutput::from(v);
1727 Box::into_raw(Box::new(out))
1728 } else {
1729 std::ptr::null_mut()
1730 }
1731}
1732
1733#[no_mangle]
1738pub unsafe extern "C" fn ymap_iter(map: *const Branch, txn: *const Transaction) -> *mut MapIter {
1739 assert!(!map.is_null());
1740
1741 let txn = txn.as_ref().unwrap();
1742 let map = &MapRef::from_raw_branch(map) as *const MapRef;
1743 Box::into_raw(Box::new(MapIter(map.as_ref().unwrap().iter(txn))))
1744}
1745
1746#[no_mangle]
1748pub unsafe extern "C" fn ymap_iter_destroy(iter: *mut MapIter) {
1749 if !iter.is_null() {
1750 drop(Box::from_raw(iter))
1751 }
1752}
1753
1754#[no_mangle]
1760pub unsafe extern "C" fn ymap_iter_next(iter: *mut MapIter) -> *mut YMapEntry {
1761 assert!(!iter.is_null());
1762
1763 let iter = iter.as_mut().unwrap();
1764 if let Some((key, value)) = iter.0.next() {
1765 let output = YOutput::from(value);
1766 Box::into_raw(Box::new(YMapEntry::new(key, Box::new(output))))
1767 } else {
1768 std::ptr::null_mut()
1769 }
1770}
1771
1772#[no_mangle]
1774pub unsafe extern "C" fn ymap_len(map: *const Branch, txn: *const Transaction) -> u32 {
1775 assert!(!map.is_null());
1776
1777 let txn = txn.as_ref().unwrap();
1778 let map = MapRef::from_raw_branch(map);
1779
1780 map.len(txn)
1781}
1782
1783#[no_mangle]
1792pub unsafe extern "C" fn ymap_insert(
1793 map: *const Branch,
1794 txn: *mut Transaction,
1795 key: *const c_char,
1796 value: *const YInput,
1797) {
1798 assert!(!map.is_null());
1799 assert!(!txn.is_null());
1800 assert!(!key.is_null());
1801 assert!(!value.is_null());
1802
1803 let cstr = CStr::from_ptr(key);
1804 let key = cstr.to_str().unwrap().to_string();
1805
1806 let map = MapRef::from_raw_branch(map);
1807 let txn = txn.as_mut().unwrap();
1808 let txn = txn
1809 .as_mut()
1810 .expect("provided transaction was not writeable");
1811
1812 map.insert(txn, key, value.read());
1813}
1814
1815#[no_mangle]
1820pub unsafe extern "C" fn ymap_remove(
1821 map: *const Branch,
1822 txn: *mut Transaction,
1823 key: *const c_char,
1824) -> u8 {
1825 assert!(!map.is_null());
1826 assert!(!txn.is_null());
1827 assert!(!key.is_null());
1828
1829 let key = CStr::from_ptr(key).to_str().unwrap();
1830
1831 let map = MapRef::from_raw_branch(map);
1832 let txn = txn.as_mut().unwrap();
1833 let txn = txn
1834 .as_mut()
1835 .expect("provided transaction was not writeable");
1836
1837 if let Some(_) = map.remove(txn, key) {
1838 Y_TRUE
1839 } else {
1840 Y_FALSE
1841 }
1842}
1843
1844#[no_mangle]
1850pub unsafe extern "C" fn ymap_get(
1851 map: *const Branch,
1852 txn: *const Transaction,
1853 key: *const c_char,
1854) -> *mut YOutput {
1855 assert!(!map.is_null());
1856 assert!(!key.is_null());
1857 assert!(!txn.is_null());
1858
1859 let txn = txn.as_ref().unwrap();
1860 let key = CStr::from_ptr(key).to_str().unwrap();
1861
1862 let map = MapRef::from_raw_branch(map);
1863
1864 if let Some(value) = map.get(txn, key) {
1865 let output = YOutput::from(value);
1866 Box::into_raw(Box::new(output))
1867 } else {
1868 std::ptr::null_mut()
1869 }
1870}
1871
1872#[no_mangle]
1881pub unsafe extern "C" fn ymap_get_json(
1882 map: *const Branch,
1883 txn: *const Transaction,
1884 key: *const c_char,
1885) -> *mut c_char {
1886 assert!(!map.is_null());
1887 assert!(!key.is_null());
1888 assert!(!txn.is_null());
1889
1890 let txn = txn.as_ref().unwrap();
1891 let key = CStr::from_ptr(key).to_str().unwrap();
1892
1893 let map = MapRef::from_raw_branch(map);
1894
1895 if let Some(value) = map.get(txn, key) {
1896 let any = value.to_json(txn);
1897 match serde_json::to_string(&any) {
1898 Ok(json) => CString::new(json).unwrap().into_raw(),
1899 Err(_) => std::ptr::null_mut(),
1900 }
1901 } else {
1902 std::ptr::null_mut()
1903 }
1904}
1905
1906#[no_mangle]
1908pub unsafe extern "C" fn ymap_remove_all(map: *const Branch, txn: *mut Transaction) {
1909 assert!(!map.is_null());
1910 assert!(!txn.is_null());
1911
1912 let map = MapRef::from_raw_branch(map);
1913 let txn = txn.as_mut().unwrap();
1914 let txn = txn
1915 .as_mut()
1916 .expect("provided transaction was not writeable");
1917
1918 map.clear(txn);
1919}
1920
1921#[no_mangle]
1927pub unsafe extern "C" fn yxmlelem_tag(xml: *const Branch) -> *mut c_char {
1928 assert!(!xml.is_null());
1929 let xml = XmlElementRef::from_raw_branch(xml);
1930 if let Some(tag) = xml.try_tag() {
1931 CString::new(tag.deref()).unwrap().into_raw()
1932 } else {
1933 null_mut()
1934 }
1935}
1936
1937#[no_mangle]
1943pub unsafe extern "C" fn yxmlelem_string(
1944 xml: *const Branch,
1945 txn: *const Transaction,
1946) -> *mut c_char {
1947 assert!(!xml.is_null());
1948 assert!(!txn.is_null());
1949
1950 let txn = txn.as_ref().unwrap();
1951 let xml = XmlElementRef::from_raw_branch(xml);
1952
1953 let str = xml.get_string(txn);
1954 CString::new(str).unwrap().into_raw()
1955}
1956
1957#[no_mangle]
1963pub unsafe extern "C" fn yxmlelem_insert_attr(
1964 xml: *const Branch,
1965 txn: *mut Transaction,
1966 attr_name: *const c_char,
1967 attr_value: *const YInput,
1968) {
1969 assert!(!xml.is_null());
1970 assert!(!txn.is_null());
1971 assert!(!attr_name.is_null());
1972 assert!(!attr_value.is_null());
1973
1974 let xml = XmlElementRef::from_raw_branch(xml);
1975 let txn = txn.as_mut().unwrap();
1976 let txn = txn
1977 .as_mut()
1978 .expect("provided transaction was not writeable");
1979
1980 let key = CStr::from_ptr(attr_name).to_str().unwrap();
1981
1982 xml.insert_attribute(txn, key, attr_value.read());
1983}
1984
1985#[no_mangle]
1989pub unsafe extern "C" fn yxmlelem_remove_attr(
1990 xml: *const Branch,
1991 txn: *mut Transaction,
1992 attr_name: *const c_char,
1993) {
1994 assert!(!xml.is_null());
1995 assert!(!txn.is_null());
1996 assert!(!attr_name.is_null());
1997
1998 let xml = XmlElementRef::from_raw_branch(xml);
1999 let txn = txn.as_mut().unwrap();
2000 let txn = txn
2001 .as_mut()
2002 .expect("provided transaction was not writeable");
2003
2004 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2005 xml.remove_attribute(txn, &key);
2006}
2007
2008#[no_mangle]
2014pub unsafe extern "C" fn yxmlelem_get_attr(
2015 xml: *const Branch,
2016 txn: *const Transaction,
2017 attr_name: *const c_char,
2018) -> *mut YOutput {
2019 assert!(!xml.is_null());
2020 assert!(!attr_name.is_null());
2021 assert!(!txn.is_null());
2022
2023 let xml = XmlElementRef::from_raw_branch(xml);
2024
2025 let key = CStr::from_ptr(attr_name).to_str().unwrap();
2026 let txn = txn.as_ref().unwrap();
2027 if let Some(value) = xml.get_attribute(txn, key) {
2028 let output = YOutput::from(value);
2029 Box::into_raw(Box::new(output))
2030 } else {
2031 std::ptr::null_mut()
2032 }
2033}
2034
2035#[no_mangle]
2040pub unsafe extern "C" fn yxmlelem_attr_iter(
2041 xml: *const Branch,
2042 txn: *const Transaction,
2043) -> *mut Attributes {
2044 assert!(!xml.is_null());
2045 assert!(!txn.is_null());
2046
2047 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2048 let txn = txn.as_ref().unwrap();
2049 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
2050}
2051
2052#[no_mangle]
2057pub unsafe extern "C" fn yxmltext_attr_iter(
2058 xml: *const Branch,
2059 txn: *const Transaction,
2060) -> *mut Attributes {
2061 assert!(!xml.is_null());
2062 assert!(!txn.is_null());
2063
2064 let xml = &XmlTextRef::from_raw_branch(xml) as *const XmlTextRef;
2065 let txn = txn.as_ref().unwrap();
2066 Box::into_raw(Box::new(Attributes(xml.as_ref().unwrap().attributes(txn))))
2067}
2068
2069#[no_mangle]
2072pub unsafe extern "C" fn yxmlattr_iter_destroy(iterator: *mut Attributes) {
2073 if !iterator.is_null() {
2074 drop(Box::from_raw(iterator))
2075 }
2076}
2077
2078#[no_mangle]
2084pub unsafe extern "C" fn yxmlattr_iter_next(iterator: *mut Attributes) -> *mut YXmlAttr {
2085 assert!(!iterator.is_null());
2086
2087 let iter = iterator.as_mut().unwrap();
2088
2089 if let Some((name, value)) = iter.0.next() {
2090 Box::into_raw(Box::new(YXmlAttr {
2091 name: CString::new(name).unwrap().into_raw(),
2092 value: Box::into_raw(Box::new(YOutput::from(value))),
2093 }))
2094 } else {
2095 std::ptr::null_mut()
2096 }
2097}
2098
2099#[no_mangle]
2107pub unsafe extern "C" fn yxml_next_sibling(
2108 xml: *const Branch,
2109 txn: *const Transaction,
2110) -> *mut YOutput {
2111 assert!(!xml.is_null());
2112 assert!(!txn.is_null());
2113
2114 let xml = XmlElementRef::from_raw_branch(xml);
2115 let txn = txn.as_ref().unwrap();
2116
2117 let mut siblings = xml.siblings(txn);
2118 if let Some(next) = siblings.next() {
2119 match next {
2120 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2121 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2122 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2123 }
2124 } else {
2125 null_mut()
2126 }
2127}
2128
2129#[no_mangle]
2135pub unsafe extern "C" fn yxml_prev_sibling(
2136 xml: *const Branch,
2137 txn: *const Transaction,
2138) -> *mut YOutput {
2139 assert!(!xml.is_null());
2140 assert!(!txn.is_null());
2141
2142 let xml = XmlElementRef::from_raw_branch(xml);
2143 let txn = txn.as_ref().unwrap();
2144
2145 let mut siblings = xml.siblings(txn);
2146 if let Some(next) = siblings.next_back() {
2147 match next {
2148 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2149 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2150 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2151 }
2152 } else {
2153 null_mut()
2154 }
2155}
2156
2157#[no_mangle]
2160pub unsafe extern "C" fn yxmlelem_parent(xml: *const Branch) -> *mut Branch {
2161 assert!(!xml.is_null());
2162
2163 let xml = XmlElementRef::from_raw_branch(xml);
2164
2165 if let Some(parent) = xml.parent() {
2166 let branch = parent.as_ptr();
2167 branch.deref() as *const Branch as *mut Branch
2168 } else {
2169 std::ptr::null_mut()
2170 }
2171}
2172
2173#[no_mangle]
2176pub unsafe extern "C" fn yxmlelem_child_len(xml: *const Branch, txn: *const Transaction) -> u32 {
2177 assert!(!xml.is_null());
2178 assert!(!txn.is_null());
2179
2180 let txn = txn.as_ref().unwrap();
2181 let xml = XmlElementRef::from_raw_branch(xml);
2182
2183 xml.len(txn) as u32
2184}
2185
2186#[no_mangle]
2191pub unsafe extern "C" fn yxmlelem_first_child(xml: *const Branch) -> *mut YOutput {
2192 assert!(!xml.is_null());
2193
2194 let xml = XmlElementRef::from_raw_branch(xml);
2195
2196 if let Some(value) = xml.first_child() {
2197 match value {
2198 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2199 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2200 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2201 }
2202 } else {
2203 std::ptr::null_mut()
2204 }
2205}
2206
2207#[no_mangle]
2213pub unsafe extern "C" fn yxmlelem_tree_walker(
2214 xml: *const Branch,
2215 txn: *const Transaction,
2216) -> *mut TreeWalker {
2217 assert!(!xml.is_null());
2218 assert!(!txn.is_null());
2219
2220 let txn = txn.as_ref().unwrap();
2221 let xml = &XmlElementRef::from_raw_branch(xml) as *const XmlElementRef;
2222 Box::into_raw(Box::new(TreeWalker(xml.as_ref().unwrap().successors(txn))))
2223}
2224
2225#[no_mangle]
2227pub unsafe extern "C" fn yxmlelem_tree_walker_destroy(iter: *mut TreeWalker) {
2228 if !iter.is_null() {
2229 drop(Box::from_raw(iter))
2230 }
2231}
2232
2233#[no_mangle]
2238pub unsafe extern "C" fn yxmlelem_tree_walker_next(iterator: *mut TreeWalker) -> *mut YOutput {
2239 assert!(!iterator.is_null());
2240
2241 let iter = iterator.as_mut().unwrap();
2242
2243 if let Some(next) = iter.0.next() {
2244 match next {
2245 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2246 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2247 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2248 }
2249 } else {
2250 std::ptr::null_mut()
2251 }
2252}
2253
2254#[no_mangle]
2263pub unsafe extern "C" fn yxmlelem_insert_elem(
2264 xml: *const Branch,
2265 txn: *mut Transaction,
2266 index: u32,
2267 name: *const c_char,
2268) -> *mut Branch {
2269 assert!(!xml.is_null());
2270 assert!(!txn.is_null());
2271 assert!(!name.is_null());
2272
2273 let xml = XmlElementRef::from_raw_branch(xml);
2274 let txn = txn.as_mut().unwrap();
2275 let txn = txn
2276 .as_mut()
2277 .expect("provided transaction was not writeable");
2278
2279 let name = CStr::from_ptr(name).to_str().unwrap();
2280 xml.insert(txn, index as u32, XmlElementPrelim::empty(name))
2281 .into_raw_branch()
2282}
2283
2284#[no_mangle]
2290pub unsafe extern "C" fn yxmlelem_insert_text(
2291 xml: *const Branch,
2292 txn: *mut Transaction,
2293 index: u32,
2294) -> *mut Branch {
2295 assert!(!xml.is_null());
2296 assert!(!txn.is_null());
2297
2298 let xml = XmlElementRef::from_raw_branch(xml);
2299 let txn = txn.as_mut().unwrap();
2300 let txn = txn
2301 .as_mut()
2302 .expect("provided transaction was not writeable");
2303 xml.insert(txn, index as u32, XmlTextPrelim::new(""))
2304 .into_raw_branch()
2305}
2306
2307#[no_mangle]
2311pub unsafe extern "C" fn yxmlelem_remove_range(
2312 xml: *const Branch,
2313 txn: *mut Transaction,
2314 index: u32,
2315 len: u32,
2316) {
2317 assert!(!xml.is_null());
2318 assert!(!txn.is_null());
2319
2320 let xml = XmlElementRef::from_raw_branch(xml);
2321 let txn = txn.as_mut().unwrap();
2322 let txn = txn
2323 .as_mut()
2324 .expect("provided transaction was not writeable");
2325
2326 xml.remove_range(txn, index as u32, len as u32)
2327}
2328
2329#[no_mangle]
2335pub unsafe extern "C" fn yxmlelem_get(
2336 xml: *const Branch,
2337 txn: *const Transaction,
2338 index: u32,
2339) -> *const YOutput {
2340 assert!(!xml.is_null());
2341 assert!(!txn.is_null());
2342
2343 let xml = XmlElementRef::from_raw_branch(xml);
2344 let txn = txn.as_ref().unwrap();
2345
2346 if let Some(child) = xml.get(txn, index as u32) {
2347 match child {
2348 XmlOut::Element(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlElement(v)))),
2349 XmlOut::Text(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlText(v)))),
2350 XmlOut::Fragment(v) => Box::into_raw(Box::new(YOutput::from(Out::YXmlFragment(v)))),
2351 }
2352 } else {
2353 std::ptr::null()
2354 }
2355}
2356
2357#[no_mangle]
2360pub unsafe extern "C" fn yxmltext_len(txt: *const Branch, txn: *const Transaction) -> u32 {
2361 assert!(!txt.is_null());
2362 assert!(!txn.is_null());
2363
2364 let txn = txn.as_ref().unwrap();
2365 let txt = XmlTextRef::from_raw_branch(txt);
2366
2367 txt.len(txn) as u32
2368}
2369
2370#[no_mangle]
2374pub unsafe extern "C" fn yxmltext_string(
2375 txt: *const Branch,
2376 txn: *const Transaction,
2377) -> *mut c_char {
2378 assert!(!txt.is_null());
2379 assert!(!txn.is_null());
2380
2381 let txn = txn.as_ref().unwrap();
2382 let txt = XmlTextRef::from_raw_branch(txt);
2383
2384 let str = txt.get_string(txn);
2385 CString::new(str).unwrap().into_raw()
2386}
2387
2388#[no_mangle]
2399pub unsafe extern "C" fn yxmltext_insert(
2400 txt: *const Branch,
2401 txn: *mut Transaction,
2402 index: u32,
2403 str: *const c_char,
2404 attrs: *const YInput,
2405) {
2406 assert!(!txt.is_null());
2407 assert!(!txn.is_null());
2408 assert!(!str.is_null());
2409
2410 let txt = XmlTextRef::from_raw_branch(txt);
2411 let txn = txn.as_mut().unwrap();
2412 let txn = txn
2413 .as_mut()
2414 .expect("provided transaction was not writeable");
2415 let chunk = CStr::from_ptr(str).to_str().unwrap();
2416
2417 if attrs.is_null() {
2418 txt.insert(txn, index as u32, chunk)
2419 } else {
2420 if let Some(attrs) = map_attrs(attrs.read().into()) {
2421 txt.insert_with_attributes(txn, index as u32, chunk, attrs)
2422 } else {
2423 panic!("yxmltext_insert: passed attributes are not of map type")
2424 }
2425 }
2426}
2427
2428#[no_mangle]
2439pub unsafe extern "C" fn yxmltext_insert_embed(
2440 txt: *const Branch,
2441 txn: *mut Transaction,
2442 index: u32,
2443 content: *const YInput,
2444 attrs: *const YInput,
2445) {
2446 assert!(!txt.is_null());
2447 assert!(!txn.is_null());
2448 assert!(!content.is_null());
2449
2450 let txn = txn.as_mut().unwrap();
2451 let txn = txn
2452 .as_mut()
2453 .expect("provided transaction was not writeable");
2454 let txt = XmlTextRef::from_raw_branch(txt);
2455 let index = index as u32;
2456 let content = content.read();
2457 if attrs.is_null() {
2458 txt.insert_embed(txn, index, content);
2459 } else {
2460 if let Some(attrs) = map_attrs(attrs.read().into()) {
2461 txt.insert_embed_with_attributes(txn, index, content, attrs);
2462 } else {
2463 panic!("yxmltext_insert_embed: passed attributes are not of map type")
2464 }
2465 }
2466}
2467
2468#[no_mangle]
2471pub unsafe extern "C" fn yxmltext_format(
2472 txt: *const Branch,
2473 txn: *mut Transaction,
2474 index: u32,
2475 len: u32,
2476 attrs: *const YInput,
2477) {
2478 assert!(!txt.is_null());
2479 assert!(!txn.is_null());
2480 assert!(!attrs.is_null());
2481
2482 if let Some(attrs) = map_attrs(attrs.read().into()) {
2483 let txt = XmlTextRef::from_raw_branch(txt);
2484 let txn = txn.as_mut().unwrap();
2485 let txn = txn
2486 .as_mut()
2487 .expect("provided transaction was not writeable");
2488 let index = index as u32;
2489 let len = len as u32;
2490 txt.format(txn, index, len, attrs);
2491 } else {
2492 panic!("yxmltext_format: passed attributes are not of map type")
2493 }
2494}
2495
2496#[no_mangle]
2505pub unsafe extern "C" fn yxmltext_remove_range(
2506 txt: *const Branch,
2507 txn: *mut Transaction,
2508 idx: u32,
2509 len: u32,
2510) {
2511 assert!(!txt.is_null());
2512 assert!(!txn.is_null());
2513
2514 let txt = XmlTextRef::from_raw_branch(txt);
2515 let txn = txn.as_mut().unwrap();
2516 let txn = txn
2517 .as_mut()
2518 .expect("provided transaction was not writeable");
2519 txt.remove_range(txn, idx as u32, len as u32)
2520}
2521
2522#[no_mangle]
2528pub unsafe extern "C" fn yxmltext_insert_attr(
2529 txt: *const Branch,
2530 txn: *mut Transaction,
2531 attr_name: *const c_char,
2532 attr_value: *const YInput,
2533) {
2534 assert!(!txt.is_null());
2535 assert!(!txn.is_null());
2536 assert!(!attr_name.is_null());
2537 assert!(!attr_value.is_null());
2538
2539 let txt = XmlTextRef::from_raw_branch(txt);
2540 let txn = txn.as_mut().unwrap();
2541 let txn = txn
2542 .as_mut()
2543 .expect("provided transaction was not writeable");
2544
2545 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2546
2547 txt.insert_attribute(txn, name, attr_value.read());
2548}
2549
2550#[no_mangle]
2554pub unsafe extern "C" fn yxmltext_remove_attr(
2555 txt: *const Branch,
2556 txn: *mut Transaction,
2557 attr_name: *const c_char,
2558) {
2559 assert!(!txt.is_null());
2560 assert!(!txn.is_null());
2561 assert!(!attr_name.is_null());
2562
2563 let txt = XmlTextRef::from_raw_branch(txt);
2564 let txn = txn.as_mut().unwrap();
2565 let txn = txn
2566 .as_mut()
2567 .expect("provided transaction was not writeable");
2568 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2569
2570 txt.remove_attribute(txn, &name)
2571}
2572
2573#[no_mangle]
2579pub unsafe extern "C" fn yxmltext_get_attr(
2580 txt: *const Branch,
2581 txn: *const Transaction,
2582 attr_name: *const c_char,
2583) -> *mut YOutput {
2584 assert!(!txt.is_null());
2585 assert!(!attr_name.is_null());
2586 assert!(!txn.is_null());
2587
2588 let txn = txn.as_ref().unwrap();
2589 let txt = XmlTextRef::from_raw_branch(txt);
2590 let name = CStr::from_ptr(attr_name).to_str().unwrap();
2591
2592 if let Some(value) = txt.get_attribute(txn, name) {
2593 let output = YOutput::from(value);
2594 Box::into_raw(Box::new(output))
2595 } else {
2596 std::ptr::null_mut()
2597 }
2598}
2599
2600#[no_mangle]
2606pub unsafe extern "C" fn ytext_chunks(
2607 txt: *const Branch,
2608 txn: *const Transaction,
2609 chunks_len: *mut u32,
2610) -> *mut YChunk {
2611 assert!(!txt.is_null());
2612 assert!(!txn.is_null());
2613
2614 let txt = TextRef::from_raw_branch(txt);
2615 let txn = txn.as_ref().unwrap();
2616
2617 let diffs = txt.diff(txn, YChange::identity);
2618 let chunks: Vec<_> = diffs.into_iter().map(YChunk::from).collect();
2619 let out = chunks.into_boxed_slice();
2620 *chunks_len = out.len() as u32;
2621 Box::into_raw(out) as *mut _
2622}
2623
2624#[no_mangle]
2626pub unsafe extern "C" fn ychunks_destroy(chunks: *mut YChunk, len: u32) {
2627 drop(Vec::from_raw_parts(chunks, len as usize, len as usize));
2628}
2629
2630pub const YCHANGE_ADD: i8 = 1;
2631pub const YCHANGE_RETAIN: i8 = 0;
2632pub const YCHANGE_REMOVE: i8 = -1;
2633
2634#[repr(C)]
2636pub struct YChunk {
2637 pub data: YOutput,
2640 pub fmt_len: u32,
2642 pub fmt: *mut YMapEntry,
2644}
2645
2646impl From<Diff<YChange>> for YChunk {
2647 fn from(diff: Diff<YChange>) -> Self {
2648 let data = YOutput::from(diff.insert);
2649 let mut fmt_len = 0;
2650 let fmt = if let Some(attrs) = diff.attributes {
2651 fmt_len = attrs.len() as u32;
2652 let mut fmt = Vec::with_capacity(attrs.len());
2653 for (k, v) in attrs.into_iter() {
2654 let output = YOutput::from(&v); let e = YMapEntry::new(k.as_ref(), Box::new(output));
2656 fmt.push(e);
2657 }
2658 Box::into_raw(fmt.into_boxed_slice()) as *mut _
2659 } else {
2660 null_mut()
2661 };
2662 YChunk { data, fmt_len, fmt }
2663 }
2664}
2665
2666impl Drop for YChunk {
2667 fn drop(&mut self) {
2668 if !self.fmt.is_null() {
2669 drop(unsafe {
2670 Vec::from_raw_parts(self.fmt, self.fmt_len as usize, self.fmt_len as usize)
2671 });
2672 }
2673 }
2674}
2675
2676#[repr(C)]
2683pub struct YInput {
2684 pub tag: i8,
2701
2702 pub len: u32,
2711
2712 value: YInputContent,
2714}
2715
2716impl YInput {
2717 fn into(self) -> Any {
2718 let tag = self.tag;
2719 unsafe {
2720 match tag {
2721 Y_JSON_STR => {
2722 let str = CStr::from_ptr(self.value.str).to_str().unwrap().into();
2723 Any::String(str)
2724 }
2725 Y_JSON => {
2726 let json_str = CStr::from_ptr(self.value.str).to_str().unwrap();
2727 serde_json::from_str(json_str).unwrap()
2728 }
2729 Y_JSON_NULL => Any::Null,
2730 Y_JSON_UNDEF => Any::Undefined,
2731 Y_JSON_INT => Any::BigInt(self.value.integer),
2732 Y_JSON_NUM => Any::Number(self.value.num),
2733 Y_JSON_BOOL => Any::Bool(if self.value.flag == 0 { false } else { true }),
2734 Y_JSON_BUF => Any::from(std::slice::from_raw_parts(
2735 self.value.buf as *mut u8,
2736 self.len as usize,
2737 )),
2738 Y_JSON_ARR => {
2739 let ptr = self.value.values;
2740 let mut dst: Vec<Any> = Vec::with_capacity(self.len as usize);
2741 let mut i = 0;
2742 while i < self.len as isize {
2743 let value = ptr.offset(i).read();
2744 let any = value.into();
2745 dst.push(any);
2746 i += 1;
2747 }
2748 Any::from(dst)
2749 }
2750 Y_JSON_MAP => {
2751 let mut dst = HashMap::with_capacity(self.len as usize);
2752 let keys = self.value.map.keys;
2753 let values = self.value.map.values;
2754 let mut i = 0;
2755 while i < self.len as isize {
2756 let key = CStr::from_ptr(keys.offset(i).read())
2757 .to_str()
2758 .unwrap()
2759 .to_owned();
2760 let value = values.offset(i).read().into();
2761 dst.insert(key, value);
2762 i += 1;
2763 }
2764 Any::from(dst)
2765 }
2766 Y_DOC => Any::Undefined,
2767 other => panic!("Cannot convert input - unknown tag: {}", other),
2768 }
2769 }
2770 }
2771}
2772
2773impl Into<EmbedPrelim<YInput>> for YInput {
2774 fn into(self) -> EmbedPrelim<YInput> {
2775 if self.tag <= 0 {
2776 EmbedPrelim::Primitive(self.into())
2777 } else {
2778 EmbedPrelim::Shared(self)
2779 }
2780 }
2781}
2782
2783#[repr(C)]
2784union YInputContent {
2785 flag: u8,
2786 num: f64,
2787 integer: i64,
2788 str: *mut c_char,
2789 buf: *mut c_char,
2790 values: *mut YInput,
2791 map: ManuallyDrop<YMapInputData>,
2792 doc: *mut Doc,
2793 weak: *const Weak,
2794}
2795
2796#[repr(C)]
2797struct YMapInputData {
2798 keys: *mut *mut c_char,
2799 values: *mut YInput,
2800}
2801
2802impl Drop for YInput {
2803 fn drop(&mut self) {}
2804}
2805
2806impl Prelim for YInput {
2807 type Return = Unused;
2808
2809 fn into_content<'doc>(self, _: &mut yrs::TransactionMut<'doc>) -> (ItemContent, Option<Self>) {
2810 unsafe {
2811 if self.tag <= 0 {
2812 (ItemContent::Any(vec![self.into()]), None)
2813 } else if self.tag == Y_DOC {
2814 let doc = self.value.doc.as_ref().unwrap();
2815 (ItemContent::Doc(None, doc.clone()), None)
2816 } else {
2817 let type_ref = match self.tag {
2818 Y_MAP => TypeRef::Map,
2819 Y_ARRAY => TypeRef::Array,
2820 Y_TEXT => TypeRef::Text,
2821 Y_XML_TEXT => TypeRef::XmlText,
2822 Y_XML_ELEM => {
2823 let name: Arc<str> =
2824 CStr::from_ptr(self.value.str).to_str().unwrap().into();
2825 TypeRef::XmlElement(name)
2826 }
2827 Y_WEAK_LINK => {
2828 let source = Arc::from_raw(self.value.weak);
2829 TypeRef::WeakLink(source)
2830 }
2831 Y_XML_FRAG => TypeRef::XmlFragment,
2832 other => panic!("unrecognized YInput tag: {}", other),
2833 };
2834 let inner = Branch::new(type_ref);
2835 (ItemContent::Type(inner), Some(self))
2836 }
2837 }
2838 }
2839
2840 fn integrate(self, txn: &mut yrs::TransactionMut, inner_ref: BranchPtr) {
2841 unsafe {
2842 match self.tag {
2843 Y_MAP => {
2844 let map = MapRef::from(inner_ref);
2845 let keys = self.value.map.keys;
2846 let values = self.value.map.values;
2847 let mut i = 0;
2848 while i < self.len as isize {
2849 let key = CStr::from_ptr(keys.offset(i).read())
2850 .to_str()
2851 .unwrap()
2852 .to_owned();
2853 let value = values.offset(i).read();
2854 map.insert(txn, key, value);
2855 i += 1;
2856 }
2857 }
2858 Y_ARRAY => {
2859 let array = ArrayRef::from(inner_ref);
2860 let ptr = self.value.values;
2861 let len = self.len as isize;
2862 let mut i = 0;
2863 while i < len {
2864 let value = ptr.offset(i).read();
2865 array.push_back(txn, value);
2866 i += 1;
2867 }
2868 }
2869 Y_TEXT => {
2870 let text = TextRef::from(inner_ref);
2871 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2872 text.push(txn, init);
2873 }
2874 Y_XML_TEXT => {
2875 let text = XmlTextRef::from(inner_ref);
2876 let init = CStr::from_ptr(self.value.str).to_str().unwrap();
2877 text.push(txn, init);
2878 }
2879 _ => { }
2880 }
2881 }
2882 }
2883}
2884
2885#[repr(C)]
2891pub struct YOutput {
2892 pub tag: i8,
2910
2911 pub len: u32,
2919
2920 value: YOutputContent,
2922}
2923
2924impl YOutput {
2925 #[inline]
2926 unsafe fn null() -> YOutput {
2927 YOutput {
2928 tag: Y_JSON_NULL,
2929 len: 0,
2930 value: MaybeUninit::uninit().assume_init(),
2931 }
2932 }
2933
2934 #[inline]
2935 unsafe fn undefined() -> YOutput {
2936 YOutput {
2937 tag: Y_JSON_UNDEF,
2938 len: 0,
2939 value: MaybeUninit::uninit().assume_init(),
2940 }
2941 }
2942}
2943
2944impl std::fmt::Display for YOutput {
2945 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2946 let tag = self.tag;
2947 unsafe {
2948 if tag == Y_JSON_INT {
2949 write!(f, "{}", self.value.integer)
2950 } else if tag == Y_JSON_NUM {
2951 write!(f, "{}", self.value.num)
2952 } else if tag == Y_JSON_BOOL {
2953 write!(
2954 f,
2955 "{}",
2956 if self.value.flag == 0 {
2957 "false"
2958 } else {
2959 "true"
2960 }
2961 )
2962 } else if tag == Y_JSON_UNDEF {
2963 write!(f, "undefined")
2964 } else if tag == Y_JSON_NULL {
2965 write!(f, "null")
2966 } else if tag == Y_JSON_STR {
2967 write!(f, "{}", CString::from_raw(self.value.str).to_str().unwrap())
2968 } else if tag == Y_MAP {
2969 write!(f, "YMap")
2970 } else if tag == Y_ARRAY {
2971 write!(f, "YArray")
2972 } else if tag == Y_JSON_ARR {
2973 write!(f, "[")?;
2974 let slice = std::slice::from_raw_parts(self.value.array, self.len as usize);
2975 for o in slice {
2976 write!(f, ", {}", o)?;
2977 }
2978 write!(f, "]")
2979 } else if tag == Y_JSON_MAP {
2980 write!(f, "{{")?;
2981 let slice = std::slice::from_raw_parts(self.value.map, self.len as usize);
2982 for e in slice {
2983 let key = CStr::from_ptr(e.key).to_str().unwrap();
2984 let value = e.value.as_ref().unwrap();
2985 write!(f, ", '{}' => {}", key, value)?;
2986 }
2987 write!(f, "}}")
2988 } else if tag == Y_TEXT {
2989 write!(f, "YText")
2990 } else if tag == Y_XML_TEXT {
2991 write!(f, "YXmlText")
2992 } else if tag == Y_XML_ELEM {
2993 write!(f, "YXmlElement",)
2994 } else if tag == Y_JSON_BUF {
2995 write!(f, "YBinary(len: {})", self.len)
2996 } else {
2997 Ok(())
2998 }
2999 }
3000 }
3001}
3002
3003impl Drop for YOutput {
3004 fn drop(&mut self) {
3005 let tag = self.tag;
3006 unsafe {
3007 match tag {
3008 Y_JSON_STR => drop(CString::from_raw(self.value.str)),
3009 Y_JSON_ARR => drop(Vec::from_raw_parts(
3010 self.value.array,
3011 self.len as usize,
3012 self.len as usize,
3013 )),
3014 Y_JSON_MAP => drop(Vec::from_raw_parts(
3015 self.value.map,
3016 self.len as usize,
3017 self.len as usize,
3018 )),
3019 Y_JSON_BUF => drop(Vec::from_raw_parts(
3020 self.value.buf as *mut u8,
3022 self.len as usize,
3023 self.len as usize,
3024 )),
3025 Y_DOC => drop(Box::from_raw(self.value.y_doc)),
3026 _ => { }
3027 }
3028 }
3029 }
3030}
3031
3032impl From<Out> for YOutput {
3033 fn from(v: Out) -> Self {
3034 match v {
3035 Out::Any(v) => Self::from(v),
3036 Out::YText(v) => Self::from(v),
3037 Out::YArray(v) => Self::from(v),
3038 Out::YMap(v) => Self::from(v),
3039 Out::YXmlElement(v) => Self::from(v),
3040 Out::YXmlFragment(v) => Self::from(v),
3041 Out::YXmlText(v) => Self::from(v),
3042 Out::YDoc(v) => Self::from(v),
3043 Out::YWeakLink(v) => Self::from(v),
3044 Out::UndefinedRef(v) => Self::from(v),
3045 }
3046 }
3047}
3048
3049impl From<bool> for YOutput {
3050 #[inline]
3051 fn from(value: bool) -> Self {
3052 YOutput {
3053 tag: Y_JSON_BOOL,
3054 len: 1,
3055 value: YOutputContent {
3056 flag: if value { Y_TRUE } else { Y_FALSE },
3057 },
3058 }
3059 }
3060}
3061
3062impl From<f64> for YOutput {
3063 #[inline]
3064 fn from(value: f64) -> Self {
3065 YOutput {
3066 tag: Y_JSON_NUM,
3067 len: 1,
3068 value: YOutputContent { num: value },
3069 }
3070 }
3071}
3072
3073impl From<i64> for YOutput {
3074 #[inline]
3075 fn from(value: i64) -> Self {
3076 YOutput {
3077 tag: Y_JSON_INT,
3078 len: 1,
3079 value: YOutputContent { integer: value },
3080 }
3081 }
3082}
3083
3084impl<'a> From<&'a str> for YOutput {
3085 fn from(value: &'a str) -> Self {
3086 YOutput {
3087 tag: Y_JSON_STR,
3088 len: value.len() as u32,
3089 value: YOutputContent {
3090 str: CString::new(value).unwrap().into_raw(),
3091 },
3092 }
3093 }
3094}
3095
3096impl<'a> From<&'a [u8]> for YOutput {
3097 fn from(value: &'a [u8]) -> Self {
3098 let value: Box<[u8]> = value.into();
3099 YOutput {
3100 tag: Y_JSON_BUF,
3101 len: value.len() as u32,
3102 value: YOutputContent {
3103 buf: Box::into_raw(value) as *const u8 as *mut c_char,
3104 },
3105 }
3106 }
3107}
3108
3109impl<'a> From<&'a [Any]> for YOutput {
3110 fn from(values: &'a [Any]) -> Self {
3111 let len = values.len() as u32;
3112 let mut array = Vec::with_capacity(values.len());
3113 for v in values.iter() {
3114 let output = YOutput::from(v);
3115 array.push(output);
3116 }
3117 let ptr = array.as_mut_ptr();
3118 forget(array);
3119 YOutput {
3120 tag: Y_JSON_ARR,
3121 len,
3122 value: YOutputContent { array: ptr },
3123 }
3124 }
3125}
3126
3127impl<'a> From<&'a HashMap<String, Any>> for YOutput {
3128 fn from(value: &'a HashMap<String, Any>) -> Self {
3129 let len = value.len() as u32;
3130 let mut array = Vec::with_capacity(len as usize);
3131 for (k, v) in value.iter() {
3132 let entry = YMapEntry::new(k.as_str(), Box::new(YOutput::from(v)));
3133 array.push(entry);
3134 }
3135 let ptr = array.as_mut_ptr();
3136 forget(array);
3137 YOutput {
3138 tag: Y_JSON_MAP,
3139 len,
3140 value: YOutputContent { map: ptr },
3141 }
3142 }
3143}
3144
3145impl<'a> From<&'a Any> for YOutput {
3146 fn from(v: &'a Any) -> Self {
3147 unsafe {
3148 match v {
3149 Any::Null => YOutput::null(),
3150 Any::Undefined => YOutput::undefined(),
3151 Any::Bool(v) => YOutput::from(*v),
3152 Any::Number(v) => YOutput::from(*v),
3153 Any::BigInt(v) => YOutput::from(*v),
3154 Any::String(v) => YOutput::from(v.as_ref()),
3155 Any::Buffer(v) => YOutput::from(v.as_ref()),
3156 Any::Array(v) => YOutput::from(v.as_ref()),
3157 Any::Map(v) => YOutput::from(v.as_ref()),
3158 }
3159 }
3160 }
3161}
3162
3163impl From<Any> for YOutput {
3164 fn from(v: Any) -> Self {
3165 unsafe {
3166 match v {
3167 Any::Null => YOutput::null(),
3168 Any::Undefined => YOutput::undefined(),
3169 Any::Bool(v) => YOutput::from(v),
3170 Any::Number(v) => YOutput::from(v),
3171 Any::BigInt(v) => YOutput::from(v),
3172 Any::String(v) => YOutput::from(v.as_ref()),
3173 Any::Buffer(v) => YOutput::from(v.as_ref()),
3174 Any::Array(v) => YOutput::from(v.as_ref()),
3175 Any::Map(v) => YOutput::from(v.as_ref()),
3176 }
3177 }
3178 }
3179}
3180
3181impl From<TextRef> for YOutput {
3182 fn from(v: TextRef) -> Self {
3183 YOutput {
3184 tag: Y_TEXT,
3185 len: 1,
3186 value: YOutputContent {
3187 y_type: v.into_raw_branch(),
3188 },
3189 }
3190 }
3191}
3192
3193impl From<ArrayRef> for YOutput {
3194 fn from(v: ArrayRef) -> Self {
3195 YOutput {
3196 tag: Y_ARRAY,
3197 len: 1,
3198 value: YOutputContent {
3199 y_type: v.into_raw_branch(),
3200 },
3201 }
3202 }
3203}
3204
3205impl From<WeakRef<BranchPtr>> for YOutput {
3206 fn from(v: WeakRef<BranchPtr>) -> Self {
3207 YOutput {
3208 tag: Y_WEAK_LINK,
3209 len: 1,
3210 value: YOutputContent {
3211 y_type: v.into_raw_branch(),
3212 },
3213 }
3214 }
3215}
3216
3217impl From<MapRef> for YOutput {
3218 fn from(v: MapRef) -> Self {
3219 YOutput {
3220 tag: Y_MAP,
3221 len: 1,
3222 value: YOutputContent {
3223 y_type: v.into_raw_branch(),
3224 },
3225 }
3226 }
3227}
3228
3229impl From<BranchPtr> for YOutput {
3230 fn from(v: BranchPtr) -> Self {
3231 let branch_ref = v.as_ref();
3232 YOutput {
3233 tag: Y_UNDEFINED,
3234 len: 1,
3235 value: YOutputContent {
3236 y_type: branch_ref as *const Branch as *mut Branch,
3237 },
3238 }
3239 }
3240}
3241
3242impl From<XmlElementRef> for YOutput {
3243 fn from(v: XmlElementRef) -> Self {
3244 YOutput {
3245 tag: Y_XML_ELEM,
3246 len: 1,
3247 value: YOutputContent {
3248 y_type: v.into_raw_branch(),
3249 },
3250 }
3251 }
3252}
3253
3254impl From<XmlTextRef> for YOutput {
3255 fn from(v: XmlTextRef) -> Self {
3256 YOutput {
3257 tag: Y_XML_TEXT,
3258 len: 1,
3259 value: YOutputContent {
3260 y_type: v.into_raw_branch(),
3261 },
3262 }
3263 }
3264}
3265
3266impl From<XmlFragmentRef> for YOutput {
3267 fn from(v: XmlFragmentRef) -> Self {
3268 YOutput {
3269 tag: Y_XML_FRAG,
3270 len: 1,
3271 value: YOutputContent {
3272 y_type: v.into_raw_branch(),
3273 },
3274 }
3275 }
3276}
3277
3278impl From<Doc> for YOutput {
3279 fn from(v: Doc) -> Self {
3280 YOutput {
3281 tag: Y_DOC,
3282 len: 1,
3283 value: YOutputContent {
3284 y_doc: Box::into_raw(Box::new(v.clone())),
3285 },
3286 }
3287 }
3288}
3289
3290#[repr(C)]
3291union YOutputContent {
3292 flag: u8,
3293 num: f64,
3294 integer: i64,
3295 str: *mut c_char,
3296 buf: *const c_char,
3297 array: *mut YOutput,
3298 map: *mut YMapEntry,
3299 y_type: *mut Branch,
3300 y_doc: *mut Doc,
3301}
3302
3303#[no_mangle]
3305pub unsafe extern "C" fn youtput_destroy(val: *mut YOutput) {
3306 if !val.is_null() {
3307 drop(Box::from_raw(val))
3308 }
3309}
3310
3311#[no_mangle]
3314pub unsafe extern "C" fn yinput_null() -> YInput {
3315 YInput {
3316 tag: Y_JSON_NULL,
3317 len: 0,
3318 value: MaybeUninit::uninit().assume_init(),
3319 }
3320}
3321
3322#[no_mangle]
3325pub unsafe extern "C" fn yinput_undefined() -> YInput {
3326 YInput {
3327 tag: Y_JSON_UNDEF,
3328 len: 0,
3329 value: MaybeUninit::uninit().assume_init(),
3330 }
3331}
3332
3333#[no_mangle]
3336pub unsafe extern "C" fn yinput_bool(flag: u8) -> YInput {
3337 YInput {
3338 tag: Y_JSON_BOOL,
3339 len: 1,
3340 value: YInputContent { flag },
3341 }
3342}
3343
3344#[no_mangle]
3347pub unsafe extern "C" fn yinput_float(num: f64) -> YInput {
3348 YInput {
3349 tag: Y_JSON_NUM,
3350 len: 1,
3351 value: YInputContent { num },
3352 }
3353}
3354
3355#[no_mangle]
3358pub unsafe extern "C" fn yinput_long(integer: i64) -> YInput {
3359 YInput {
3360 tag: Y_JSON_INT,
3361 len: 1,
3362 value: YInputContent { integer },
3363 }
3364}
3365
3366#[no_mangle]
3371pub unsafe extern "C" fn yinput_string(str: *const c_char) -> YInput {
3372 YInput {
3373 tag: Y_JSON_STR,
3374 len: 1,
3375 value: YInputContent {
3376 str: str as *mut c_char,
3377 },
3378 }
3379}
3380
3381#[no_mangle]
3387pub unsafe extern "C" fn yinput_json(str: *const c_char) -> YInput {
3388 YInput {
3389 tag: Y_JSON,
3390 len: 1,
3391 value: YInputContent {
3392 str: str as *mut c_char,
3393 },
3394 }
3395}
3396
3397#[no_mangle]
3401pub unsafe extern "C" fn yinput_binary(buf: *const c_char, len: u32) -> YInput {
3402 YInput {
3403 tag: Y_JSON_BUF,
3404 len,
3405 value: YInputContent {
3406 buf: buf as *mut c_char,
3407 },
3408 }
3409}
3410
3411#[no_mangle]
3415pub unsafe extern "C" fn yinput_json_array(values: *mut YInput, len: u32) -> YInput {
3416 YInput {
3417 tag: Y_JSON_ARR,
3418 len,
3419 value: YInputContent { values },
3420 }
3421}
3422
3423#[no_mangle]
3430pub unsafe extern "C" fn yinput_json_map(
3431 keys: *mut *mut c_char,
3432 values: *mut YInput,
3433 len: u32,
3434) -> YInput {
3435 YInput {
3436 tag: Y_JSON_MAP,
3437 len,
3438 value: YInputContent {
3439 map: ManuallyDrop::new(YMapInputData { keys, values }),
3440 },
3441 }
3442}
3443
3444#[no_mangle]
3449pub unsafe extern "C" fn yinput_yarray(values: *mut YInput, len: u32) -> YInput {
3450 YInput {
3451 tag: Y_ARRAY,
3452 len,
3453 value: YInputContent { values },
3454 }
3455}
3456
3457#[no_mangle]
3464pub unsafe extern "C" fn yinput_ymap(
3465 keys: *mut *mut c_char,
3466 values: *mut YInput,
3467 len: u32,
3468) -> YInput {
3469 YInput {
3470 tag: Y_MAP,
3471 len,
3472 value: YInputContent {
3473 map: ManuallyDrop::new(YMapInputData { keys, values }),
3474 },
3475 }
3476}
3477
3478#[no_mangle]
3484pub unsafe extern "C" fn yinput_ytext(str: *mut c_char) -> YInput {
3485 YInput {
3486 tag: Y_TEXT,
3487 len: 1,
3488 value: YInputContent { str },
3489 }
3490}
3491
3492#[no_mangle]
3498pub unsafe extern "C" fn yinput_yxmlelem(name: *mut c_char) -> YInput {
3499 YInput {
3500 tag: Y_XML_ELEM,
3501 len: 1,
3502 value: YInputContent { str: name },
3503 }
3504}
3505
3506#[no_mangle]
3512pub unsafe extern "C" fn yinput_yxmltext(str: *mut c_char) -> YInput {
3513 YInput {
3514 tag: Y_XML_TEXT,
3515 len: 1,
3516 value: YInputContent { str },
3517 }
3518}
3519
3520#[no_mangle]
3525pub unsafe extern "C" fn yinput_ydoc(doc: *mut Doc) -> YInput {
3526 YInput {
3527 tag: Y_DOC,
3528 len: 1,
3529 value: YInputContent { doc },
3530 }
3531}
3532
3533#[no_mangle]
3536pub unsafe extern "C" fn yinput_weak(weak: *const Weak) -> YInput {
3537 YInput {
3538 tag: Y_WEAK_LINK,
3539 len: 1,
3540 value: YInputContent { weak },
3541 }
3542}
3543
3544#[no_mangle]
3547pub unsafe extern "C" fn youtput_read_ydoc(val: *const YOutput) -> *mut Doc {
3548 let v = val.as_ref().unwrap();
3549 if v.tag == Y_DOC {
3550 v.value.y_doc
3551 } else {
3552 std::ptr::null_mut()
3553 }
3554}
3555
3556#[no_mangle]
3560pub unsafe extern "C" fn youtput_read_bool(val: *const YOutput) -> *const u8 {
3561 let v = val.as_ref().unwrap();
3562 if v.tag == Y_JSON_BOOL {
3563 &v.value.flag
3564 } else {
3565 std::ptr::null()
3566 }
3567}
3568
3569#[no_mangle]
3574pub unsafe extern "C" fn youtput_read_float(val: *const YOutput) -> *const f64 {
3575 let v = val.as_ref().unwrap();
3576 if v.tag == Y_JSON_NUM {
3577 &v.value.num
3578 } else {
3579 std::ptr::null()
3580 }
3581}
3582
3583#[no_mangle]
3588pub unsafe extern "C" fn youtput_read_long(val: *const YOutput) -> *const i64 {
3589 let v = val.as_ref().unwrap();
3590 if v.tag == Y_JSON_INT {
3591 &v.value.integer
3592 } else {
3593 std::ptr::null()
3594 }
3595}
3596
3597#[no_mangle]
3604pub unsafe extern "C" fn youtput_read_string(val: *const YOutput) -> *mut c_char {
3605 let v = val.as_ref().unwrap();
3606 if v.tag == Y_JSON_STR {
3607 v.value.str
3608 } else {
3609 std::ptr::null_mut()
3610 }
3611}
3612
3613#[no_mangle]
3620pub unsafe extern "C" fn youtput_read_binary(val: *const YOutput) -> *const c_char {
3621 let v = val.as_ref().unwrap();
3622 if v.tag == Y_JSON_BUF {
3623 v.value.buf
3624 } else {
3625 std::ptr::null()
3626 }
3627}
3628
3629#[no_mangle]
3636pub unsafe extern "C" fn youtput_read_json_array(val: *const YOutput) -> *mut YOutput {
3637 let v = val.as_ref().unwrap();
3638 if v.tag == Y_JSON_ARR {
3639 v.value.array
3640 } else {
3641 std::ptr::null_mut()
3642 }
3643}
3644
3645#[no_mangle]
3652pub unsafe extern "C" fn youtput_read_json_map(val: *const YOutput) -> *mut YMapEntry {
3653 let v = val.as_ref().unwrap();
3654 if v.tag == Y_JSON_MAP {
3655 v.value.map
3656 } else {
3657 std::ptr::null_mut()
3658 }
3659}
3660
3661#[no_mangle]
3667pub unsafe extern "C" fn youtput_read_yarray(val: *const YOutput) -> *mut Branch {
3668 let v = val.as_ref().unwrap();
3669 if v.tag == Y_ARRAY {
3670 v.value.y_type
3671 } else {
3672 std::ptr::null_mut()
3673 }
3674}
3675
3676#[no_mangle]
3682pub unsafe extern "C" fn youtput_read_yxmlelem(val: *const YOutput) -> *mut Branch {
3683 let v = val.as_ref().unwrap();
3684 if v.tag == Y_XML_ELEM {
3685 v.value.y_type
3686 } else {
3687 std::ptr::null_mut()
3688 }
3689}
3690
3691#[no_mangle]
3697pub unsafe extern "C" fn youtput_read_ymap(val: *const YOutput) -> *mut Branch {
3698 let v = val.as_ref().unwrap();
3699 if v.tag == Y_MAP {
3700 v.value.y_type
3701 } else {
3702 std::ptr::null_mut()
3703 }
3704}
3705
3706#[no_mangle]
3712pub unsafe extern "C" fn youtput_read_ytext(val: *const YOutput) -> *mut Branch {
3713 let v = val.as_ref().unwrap();
3714 if v.tag == Y_TEXT {
3715 v.value.y_type
3716 } else {
3717 std::ptr::null_mut()
3718 }
3719}
3720
3721#[no_mangle]
3727pub unsafe extern "C" fn youtput_read_yxmltext(val: *const YOutput) -> *mut Branch {
3728 let v = val.as_ref().unwrap();
3729 if v.tag == Y_XML_TEXT {
3730 v.value.y_type
3731 } else {
3732 std::ptr::null_mut()
3733 }
3734}
3735
3736#[no_mangle]
3742pub unsafe extern "C" fn youtput_read_yweak(val: *const YOutput) -> *mut Branch {
3743 let v = val.as_ref().unwrap();
3744 if v.tag == Y_WEAK_LINK {
3745 v.value.y_type
3746 } else {
3747 std::ptr::null_mut()
3748 }
3749}
3750
3751#[no_mangle]
3753pub unsafe extern "C" fn yunobserve(subscription: *mut Subscription) {
3754 drop(unsafe { Box::from_raw(subscription) })
3755}
3756
3757#[no_mangle]
3762pub unsafe extern "C" fn ytext_observe(
3763 txt: *const Branch,
3764 state: *mut c_void,
3765 cb: extern "C" fn(*mut c_void, *const YTextEvent),
3766) -> *mut Subscription {
3767 assert!(!txt.is_null());
3768 let state = CallbackState::new(state);
3769
3770 let txt = TextRef::from_raw_branch(txt);
3771 let subscription = txt.observe(move |txn, e| {
3772 let e = YTextEvent::new(e, txn);
3773 cb(state.0, &e as *const YTextEvent);
3774 });
3775 Box::into_raw(Box::new(subscription))
3776}
3777
3778#[no_mangle]
3783pub unsafe extern "C" fn ymap_observe(
3784 map: *const Branch,
3785 state: *mut c_void,
3786 cb: extern "C" fn(*mut c_void, *const YMapEvent),
3787) -> *mut Subscription {
3788 assert!(!map.is_null());
3789 let state = CallbackState::new(state);
3790
3791 let map = MapRef::from_raw_branch(map);
3792 let subscription = map.observe(move |txn, e| {
3793 let e = YMapEvent::new(e, txn);
3794 cb(state.0, &e as *const YMapEvent);
3795 });
3796 Box::into_raw(Box::new(subscription))
3797}
3798
3799#[no_mangle]
3804pub unsafe extern "C" fn yarray_observe(
3805 array: *const Branch,
3806 state: *mut c_void,
3807 cb: extern "C" fn(*mut c_void, *const YArrayEvent),
3808) -> *mut Subscription {
3809 assert!(!array.is_null());
3810 let state = CallbackState::new(state);
3811
3812 let array = ArrayRef::from_raw_branch(array);
3813 let subscription = array.observe(move |txn, e| {
3814 let e = YArrayEvent::new(e, txn);
3815 cb(state.0, &e as *const YArrayEvent);
3816 });
3817 Box::into_raw(Box::new(subscription))
3818}
3819
3820#[no_mangle]
3825pub unsafe extern "C" fn yxmlelem_observe(
3826 xml: *const Branch,
3827 state: *mut c_void,
3828 cb: extern "C" fn(*mut c_void, *const YXmlEvent),
3829) -> *mut Subscription {
3830 assert!(!xml.is_null());
3831 let state = CallbackState::new(state);
3832
3833 let xml = XmlElementRef::from_raw_branch(xml);
3834 let subscription = xml.observe(move |txn, e| {
3835 let e = YXmlEvent::new(e, txn);
3836 cb(state.0, &e as *const YXmlEvent);
3837 });
3838 Box::into_raw(Box::new(subscription))
3839}
3840
3841#[no_mangle]
3846pub unsafe extern "C" fn yxmltext_observe(
3847 xml: *const Branch,
3848 state: *mut c_void,
3849 cb: extern "C" fn(*mut c_void, *const YXmlTextEvent),
3850) -> *mut Subscription {
3851 assert!(!xml.is_null());
3852
3853 let state = CallbackState::new(state);
3854 let xml = XmlTextRef::from_raw_branch(xml);
3855 let subscription = xml.observe(move |txn, e| {
3856 let e = YXmlTextEvent::new(e, txn);
3857 cb(state.0, &e as *const YXmlTextEvent);
3858 });
3859 Box::into_raw(Box::new(subscription))
3860}
3861
3862#[no_mangle]
3869pub unsafe extern "C" fn yobserve_deep(
3870 ytype: *mut Branch,
3871 state: *mut c_void,
3872 cb: extern "C" fn(*mut c_void, u32, *const YEvent),
3873) -> *mut Subscription {
3874 assert!(!ytype.is_null());
3875
3876 let state = CallbackState::new(state);
3877 let branch = ytype.as_mut().unwrap();
3878 let subscription = branch.observe_deep(move |txn, events| {
3879 let events: Vec<_> = events.iter().map(|e| YEvent::new(txn, e)).collect();
3880 let len = events.len() as u32;
3881 cb(state.0, len, events.as_ptr());
3882 });
3883 Box::into_raw(Box::new(subscription))
3884}
3885
3886#[repr(C)]
3889pub struct YAfterTransactionEvent {
3890 pub before_state: YStateVector,
3892 pub after_state: YStateVector,
3894 pub delete_set: YIdSet,
3896}
3897
3898impl YAfterTransactionEvent {
3899 unsafe fn new(e: &TransactionCleanupEvent) -> Self {
3900 YAfterTransactionEvent {
3901 before_state: YStateVector::new(&e.before_state),
3902 after_state: YStateVector::new(&e.after_state),
3903 delete_set: YIdSet::new(&e.delete_set),
3904 }
3905 }
3906}
3907
3908#[repr(C)]
3909pub struct YSubdocsEvent {
3910 added_len: u32,
3911 removed_len: u32,
3912 loaded_len: u32,
3913 added: *mut *mut Doc,
3914 removed: *mut *mut Doc,
3915 loaded: *mut *mut Doc,
3916}
3917
3918impl YSubdocsEvent {
3919 unsafe fn new(e: &SubdocsEvent) -> Self {
3920 fn into_ptr(v: SubdocsEventIter) -> *mut *mut Doc {
3921 let array: Vec<_> = v.map(|doc| Box::into_raw(Box::new(doc.clone()))).collect();
3922 let mut boxed = array.into_boxed_slice();
3923 let ptr = boxed.as_mut_ptr();
3924 forget(boxed);
3925 ptr
3926 }
3927
3928 let added = e.added();
3929 let removed = e.removed();
3930 let loaded = e.loaded();
3931
3932 YSubdocsEvent {
3933 added_len: added.len() as u32,
3934 removed_len: removed.len() as u32,
3935 loaded_len: loaded.len() as u32,
3936 added: into_ptr(added),
3937 removed: into_ptr(removed),
3938 loaded: into_ptr(loaded),
3939 }
3940 }
3941}
3942
3943impl Drop for YSubdocsEvent {
3944 fn drop(&mut self) {
3945 fn release(len: u32, buf: *mut *mut Doc) {
3946 unsafe {
3947 let docs = Vec::from_raw_parts(buf, len as usize, len as usize);
3948 for d in docs {
3949 drop(Box::from_raw(d));
3950 }
3951 }
3952 }
3953
3954 release(self.added_len, self.added);
3955 release(self.removed_len, self.removed);
3956 release(self.loaded_len, self.loaded);
3957 }
3958}
3959
3960#[repr(C)]
3963pub struct YStateVector {
3964 pub entries_count: u32,
3966 pub client_ids: *mut u64,
3970 pub clocks: *mut u32,
3974}
3975
3976impl YStateVector {
3977 unsafe fn new(sv: &StateVector) -> Self {
3978 let entries_count = sv.len() as u32;
3979 let mut client_ids = Vec::with_capacity(sv.len());
3980 let mut clocks = Vec::with_capacity(sv.len());
3981 for (&client, &clock) in sv.iter() {
3982 client_ids.push(client.get());
3983 clocks.push(clock as u32);
3984 }
3985
3986 YStateVector {
3987 entries_count,
3988 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
3989 clocks: Box::into_raw(clocks.into_boxed_slice()) as *mut _,
3990 }
3991 }
3992}
3993
3994impl Drop for YStateVector {
3995 fn drop(&mut self) {
3996 let len = self.entries_count as usize;
3997 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
3998 drop(unsafe { Vec::from_raw_parts(self.clocks, len, len) });
3999 }
4000}
4001
4002#[repr(C)]
4006pub struct YIdSet {
4007 pub entries_count: u32,
4009 pub client_ids: *mut u64,
4013 pub ranges: *mut YIdRangeSeq,
4017}
4018
4019impl YIdSet {
4020 unsafe fn new(ds: &IdSet) -> Self {
4021 let len = ds.len();
4022 let mut client_ids = Vec::with_capacity(len);
4023 let mut ranges = Vec::with_capacity(len);
4024
4025 for (&client, range) in ds.iter() {
4026 client_ids.push(client.get());
4027 let seq: Vec<_> = range
4028 .iter()
4029 .map(|r| YIdRange {
4030 start: r.start as u32,
4031 end: r.end as u32,
4032 })
4033 .collect();
4034 ranges.push(YIdRangeSeq {
4035 len: seq.len() as u32,
4036 seq: Box::into_raw(seq.into_boxed_slice()) as *mut _,
4037 })
4038 }
4039
4040 YIdSet {
4041 entries_count: len as u32,
4042 client_ids: Box::into_raw(client_ids.into_boxed_slice()) as *mut _,
4043 ranges: Box::into_raw(ranges.into_boxed_slice()) as *mut _,
4044 }
4045 }
4046}
4047
4048impl Drop for YIdSet {
4049 fn drop(&mut self) {
4050 let len = self.entries_count as usize;
4051 drop(unsafe { Vec::from_raw_parts(self.client_ids, len, len) });
4052 drop(unsafe { Vec::from_raw_parts(self.ranges, len, len) });
4053 }
4054}
4055
4056#[repr(C)]
4059pub struct YIdRangeSeq {
4060 pub len: u32,
4062 pub seq: *mut YIdRange,
4066}
4067
4068impl Drop for YIdRangeSeq {
4069 fn drop(&mut self) {
4070 let len = self.len as usize;
4071 drop(unsafe { Vec::from_raw_parts(self.seq, len, len) })
4072 }
4073}
4074
4075#[repr(C)]
4076pub struct YIdRange {
4077 pub start: u32,
4078 pub end: u32,
4079}
4080
4081#[repr(C)]
4082pub struct YEvent {
4083 pub tag: i8,
4091
4092 pub content: YEventContent,
4095}
4096
4097impl YEvent {
4098 fn new<'doc>(txn: &yrs::TransactionMut<'doc>, e: &Event) -> YEvent {
4099 match e {
4100 Event::Text(e) => YEvent {
4101 tag: Y_TEXT,
4102 content: YEventContent {
4103 text: YTextEvent::new(e, txn),
4104 },
4105 },
4106 Event::Array(e) => YEvent {
4107 tag: Y_ARRAY,
4108 content: YEventContent {
4109 array: YArrayEvent::new(e, txn),
4110 },
4111 },
4112 Event::Map(e) => YEvent {
4113 tag: Y_MAP,
4114 content: YEventContent {
4115 map: YMapEvent::new(e, txn),
4116 },
4117 },
4118 Event::XmlFragment(e) => YEvent {
4119 tag: if let XmlOut::Fragment(_) = e.target() {
4120 Y_XML_FRAG
4121 } else {
4122 Y_XML_ELEM
4123 },
4124 content: YEventContent {
4125 xml_elem: YXmlEvent::new(e, txn),
4126 },
4127 },
4128 Event::XmlText(e) => YEvent {
4129 tag: Y_XML_TEXT,
4130 content: YEventContent {
4131 xml_text: YXmlTextEvent::new(e, txn),
4132 },
4133 },
4134 Event::Weak(e) => YEvent {
4135 tag: Y_WEAK_LINK,
4136 content: YEventContent {
4137 weak: YWeakLinkEvent::new(e, txn),
4138 },
4139 },
4140 }
4141 }
4142}
4143
4144#[repr(C)]
4145pub union YEventContent {
4146 pub text: YTextEvent,
4147 pub map: YMapEvent,
4148 pub array: YArrayEvent,
4149 pub xml_elem: YXmlEvent,
4150 pub xml_text: YXmlTextEvent,
4151 pub weak: YWeakLinkEvent,
4152}
4153
4154#[repr(C)]
4158#[derive(Copy, Clone)]
4159pub struct YTextEvent {
4160 inner: *const c_void,
4161 txn: *const yrs::TransactionMut<'static>,
4162}
4163
4164impl YTextEvent {
4165 fn new<'dev>(inner: &TextEvent, txn: &yrs::TransactionMut<'dev>) -> Self {
4166 let inner = inner as *const TextEvent as *const _;
4167 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4168 let txn = txn as *const _;
4169 YTextEvent { inner, txn }
4170 }
4171
4172 fn txn(&self) -> &yrs::TransactionMut {
4173 unsafe { self.txn.as_ref().unwrap() }
4174 }
4175}
4176
4177impl Deref for YTextEvent {
4178 type Target = TextEvent;
4179
4180 fn deref(&self) -> &Self::Target {
4181 unsafe { (self.inner as *const TextEvent).as_ref().unwrap() }
4182 }
4183}
4184
4185#[repr(C)]
4189#[derive(Copy, Clone)]
4190pub struct YArrayEvent {
4191 inner: *const c_void,
4192 txn: *const yrs::TransactionMut<'static>,
4193}
4194
4195impl YArrayEvent {
4196 fn new<'doc>(inner: &ArrayEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4197 let inner = inner as *const ArrayEvent as *const _;
4198 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4199 let txn = txn as *const _;
4200 YArrayEvent { inner, txn }
4201 }
4202
4203 fn txn(&self) -> &yrs::TransactionMut {
4204 unsafe { self.txn.as_ref().unwrap() }
4205 }
4206}
4207
4208impl Deref for YArrayEvent {
4209 type Target = ArrayEvent;
4210
4211 fn deref(&self) -> &Self::Target {
4212 unsafe { (self.inner as *const ArrayEvent).as_ref().unwrap() }
4213 }
4214}
4215
4216#[repr(C)]
4220#[derive(Copy, Clone)]
4221pub struct YMapEvent {
4222 inner: *const c_void,
4223 txn: *const yrs::TransactionMut<'static>,
4224}
4225
4226impl YMapEvent {
4227 fn new<'doc>(inner: &MapEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4228 let inner = inner as *const MapEvent as *const _;
4229 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4230 let txn = txn as *const _;
4231 YMapEvent { inner, txn }
4232 }
4233
4234 fn txn(&self) -> &yrs::TransactionMut<'static> {
4235 unsafe { self.txn.as_ref().unwrap() }
4236 }
4237}
4238
4239impl Deref for YMapEvent {
4240 type Target = MapEvent;
4241
4242 fn deref(&self) -> &Self::Target {
4243 unsafe { (self.inner as *const MapEvent).as_ref().unwrap() }
4244 }
4245}
4246
4247#[repr(C)]
4252#[derive(Copy, Clone)]
4253pub struct YXmlEvent {
4254 inner: *const c_void,
4255 txn: *const yrs::TransactionMut<'static>,
4256}
4257
4258impl YXmlEvent {
4259 fn new<'doc>(inner: &XmlEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4260 let inner = inner as *const XmlEvent as *const _;
4261 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4262 let txn = txn as *const _;
4263 YXmlEvent { inner, txn }
4264 }
4265
4266 fn txn(&self) -> &yrs::TransactionMut<'static> {
4267 unsafe { self.txn.as_ref().unwrap() }
4268 }
4269}
4270
4271impl Deref for YXmlEvent {
4272 type Target = XmlEvent;
4273
4274 fn deref(&self) -> &Self::Target {
4275 unsafe { (self.inner as *const XmlEvent).as_ref().unwrap() }
4276 }
4277}
4278
4279#[repr(C)]
4284#[derive(Copy, Clone)]
4285pub struct YXmlTextEvent {
4286 inner: *const c_void,
4287 txn: *const yrs::TransactionMut<'static>,
4288}
4289
4290impl YXmlTextEvent {
4291 fn new<'doc>(inner: &XmlTextEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4292 let inner = inner as *const XmlTextEvent as *const _;
4293 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4294 let txn = txn as *const _;
4295 YXmlTextEvent { inner, txn }
4296 }
4297
4298 fn txn(&self) -> &yrs::TransactionMut<'static> {
4299 unsafe { self.txn.as_ref().unwrap() }
4300 }
4301}
4302
4303impl Deref for YXmlTextEvent {
4304 type Target = XmlTextEvent;
4305
4306 fn deref(&self) -> &Self::Target {
4307 unsafe { (self.inner as *const XmlTextEvent).as_ref().unwrap() }
4308 }
4309}
4310
4311#[repr(C)]
4314#[derive(Copy, Clone)]
4315pub struct YWeakLinkEvent {
4316 inner: *const c_void,
4317 txn: *const yrs::TransactionMut<'static>,
4318}
4319
4320impl YWeakLinkEvent {
4321 fn new<'doc>(inner: &WeakEvent, txn: &yrs::TransactionMut<'doc>) -> Self {
4322 let inner = inner as *const WeakEvent as *const _;
4323 let txn: &yrs::TransactionMut<'static> = unsafe { std::mem::transmute(txn) };
4324 let txn = txn as *const _;
4325 YWeakLinkEvent { inner, txn }
4326 }
4327}
4328
4329impl Deref for YWeakLinkEvent {
4330 type Target = WeakEvent;
4331
4332 fn deref(&self) -> &Self::Target {
4333 unsafe { (self.inner as *const WeakEvent).as_ref().unwrap() }
4334 }
4335}
4336
4337#[no_mangle]
4339pub unsafe extern "C" fn ytext_event_target(e: *const YTextEvent) -> *mut Branch {
4340 assert!(!e.is_null());
4341 let out = (&*e).target().clone();
4342 out.into_raw_branch()
4343}
4344
4345#[no_mangle]
4347pub unsafe extern "C" fn yarray_event_target(e: *const YArrayEvent) -> *mut Branch {
4348 assert!(!e.is_null());
4349 let out = (&*e).target().clone();
4350 out.into_raw_branch()
4351}
4352
4353#[no_mangle]
4355pub unsafe extern "C" fn ymap_event_target(e: *const YMapEvent) -> *mut Branch {
4356 assert!(!e.is_null());
4357 let out = (&*e).target().clone();
4358 out.into_raw_branch()
4359}
4360
4361#[no_mangle]
4363pub unsafe extern "C" fn yxmlelem_event_target(e: *const YXmlEvent) -> *mut Branch {
4364 assert!(!e.is_null());
4365 let out = (&*e).target().clone();
4366 match out {
4367 XmlOut::Element(e) => e.into_raw_branch(),
4368 XmlOut::Fragment(e) => e.into_raw_branch(),
4369 XmlOut::Text(e) => e.into_raw_branch(),
4370 }
4371}
4372
4373#[no_mangle]
4375pub unsafe extern "C" fn yxmltext_event_target(e: *const YXmlTextEvent) -> *mut Branch {
4376 assert!(!e.is_null());
4377 let out = (&*e).target().clone();
4378 out.into_raw_branch()
4379}
4380
4381#[no_mangle]
4388pub unsafe extern "C" fn ytext_event_path(
4389 e: *const YTextEvent,
4390 len: *mut u32,
4391) -> *mut YPathSegment {
4392 assert!(!e.is_null());
4393 let e = &*e;
4394 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4395 let out = path.into_boxed_slice();
4396 *len = out.len() as u32;
4397 Box::into_raw(out) as *mut _
4398}
4399
4400#[no_mangle]
4407pub unsafe extern "C" fn ymap_event_path(e: *const YMapEvent, len: *mut u32) -> *mut YPathSegment {
4408 assert!(!e.is_null());
4409 let e = &*e;
4410 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4411 let out = path.into_boxed_slice();
4412 *len = out.len() as u32;
4413 Box::into_raw(out) as *mut _
4414}
4415
4416#[no_mangle]
4423pub unsafe extern "C" fn yxmlelem_event_path(
4424 e: *const YXmlEvent,
4425 len: *mut u32,
4426) -> *mut YPathSegment {
4427 assert!(!e.is_null());
4428 let e = &*e;
4429 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4430 let out = path.into_boxed_slice();
4431 *len = out.len() as u32;
4432 Box::into_raw(out) as *mut _
4433}
4434
4435#[no_mangle]
4442pub unsafe extern "C" fn yxmltext_event_path(
4443 e: *const YXmlTextEvent,
4444 len: *mut u32,
4445) -> *mut YPathSegment {
4446 assert!(!e.is_null());
4447 let e = &*e;
4448 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4449 let out = path.into_boxed_slice();
4450 *len = out.len() as u32;
4451 Box::into_raw(out) as *mut _
4452}
4453
4454#[no_mangle]
4461pub unsafe extern "C" fn yarray_event_path(
4462 e: *const YArrayEvent,
4463 len: *mut u32,
4464) -> *mut YPathSegment {
4465 assert!(!e.is_null());
4466 let e = &*e;
4467 let path: Vec<_> = e.path().into_iter().map(YPathSegment::from).collect();
4468 let out = path.into_boxed_slice();
4469 *len = out.len() as u32;
4470 Box::into_raw(out) as *mut _
4471}
4472
4473#[no_mangle]
4476pub unsafe extern "C" fn ypath_destroy(path: *mut YPathSegment, len: u32) {
4477 if !path.is_null() {
4478 drop(Vec::from_raw_parts(path, len as usize, len as usize));
4479 }
4480}
4481
4482#[no_mangle]
4489pub unsafe extern "C" fn ytext_event_delta(e: *const YTextEvent, len: *mut u32) -> *mut YDeltaOut {
4490 assert!(!e.is_null());
4491 let e = &*e;
4492 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4493
4494 let out = delta.into_boxed_slice();
4495 *len = out.len() as u32;
4496 Box::into_raw(out) as *mut _
4497}
4498
4499#[no_mangle]
4506pub unsafe extern "C" fn yxmltext_event_delta(
4507 e: *const YXmlTextEvent,
4508 len: *mut u32,
4509) -> *mut YDeltaOut {
4510 assert!(!e.is_null());
4511 let e = &*e;
4512 let delta: Vec<_> = e.delta(e.txn()).into_iter().map(YDeltaOut::from).collect();
4513
4514 let out = delta.into_boxed_slice();
4515 *len = out.len() as u32;
4516 Box::into_raw(out) as *mut _
4517}
4518
4519#[no_mangle]
4526pub unsafe extern "C" fn yarray_event_delta(
4527 e: *const YArrayEvent,
4528 len: *mut u32,
4529) -> *mut YEventChange {
4530 assert!(!e.is_null());
4531 let e = &*e;
4532 let delta: Vec<_> = e
4533 .delta(e.txn())
4534 .into_iter()
4535 .map(YEventChange::from)
4536 .collect();
4537
4538 let out = delta.into_boxed_slice();
4539 *len = out.len() as u32;
4540 Box::into_raw(out) as *mut _
4541}
4542
4543#[no_mangle]
4550pub unsafe extern "C" fn yxmlelem_event_delta(
4551 e: *const YXmlEvent,
4552 len: *mut u32,
4553) -> *mut YEventChange {
4554 assert!(!e.is_null());
4555 let e = &*e;
4556 let delta: Vec<_> = e
4557 .delta(e.txn())
4558 .into_iter()
4559 .map(YEventChange::from)
4560 .collect();
4561
4562 let out = delta.into_boxed_slice();
4563 *len = out.len() as u32;
4564 Box::into_raw(out) as *mut _
4565}
4566
4567#[no_mangle]
4569pub unsafe extern "C" fn ytext_delta_destroy(delta: *mut YDeltaOut, len: u32) {
4570 if !delta.is_null() {
4571 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4572 drop(delta);
4573 }
4574}
4575
4576#[no_mangle]
4578pub unsafe extern "C" fn yevent_delta_destroy(delta: *mut YEventChange, len: u32) {
4579 if !delta.is_null() {
4580 let delta = Vec::from_raw_parts(delta, len as usize, len as usize);
4581 drop(delta);
4582 }
4583}
4584
4585#[no_mangle]
4592pub unsafe extern "C" fn ymap_event_keys(
4593 e: *const YMapEvent,
4594 len: *mut u32,
4595) -> *mut YEventKeyChange {
4596 assert!(!e.is_null());
4597 let e = &*e;
4598 let delta: Vec<_> = e
4599 .keys(e.txn())
4600 .into_iter()
4601 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4602 .collect();
4603
4604 let out = delta.into_boxed_slice();
4605 *len = out.len() as u32;
4606 Box::into_raw(out) as *mut _
4607}
4608
4609#[no_mangle]
4615pub unsafe extern "C" fn yxmlelem_event_keys(
4616 e: *const YXmlEvent,
4617 len: *mut u32,
4618) -> *mut YEventKeyChange {
4619 assert!(!e.is_null());
4620 let e = &*e;
4621 let delta: Vec<_> = e
4622 .keys(e.txn())
4623 .into_iter()
4624 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4625 .collect();
4626
4627 let out = delta.into_boxed_slice();
4628 *len = out.len() as u32;
4629 Box::into_raw(out) as *mut _
4630}
4631
4632#[no_mangle]
4638pub unsafe extern "C" fn yxmltext_event_keys(
4639 e: *const YXmlTextEvent,
4640 len: *mut u32,
4641) -> *mut YEventKeyChange {
4642 assert!(!e.is_null());
4643 let e = &*e;
4644 let delta: Vec<_> = e
4645 .keys(e.txn())
4646 .into_iter()
4647 .map(|(k, v)| YEventKeyChange::new(k.as_ref(), v))
4648 .collect();
4649
4650 let out = delta.into_boxed_slice();
4651 *len = out.len() as u32;
4652 Box::into_raw(out) as *mut _
4653}
4654
4655#[no_mangle]
4658pub unsafe extern "C" fn yevent_keys_destroy(keys: *mut YEventKeyChange, len: u32) {
4659 if !keys.is_null() {
4660 drop(Vec::from_raw_parts(keys, len as usize, len as usize));
4661 }
4662}
4663
4664pub type YUndoManager = yrs::undo::UndoManager<AtomicPtr<c_void>>;
4665
4666#[repr(C)]
4667pub struct YUndoManagerOptions {
4668 pub capture_timeout_millis: i32,
4669}
4670
4671#[no_mangle]
4679pub unsafe extern "C" fn yundo_manager(options: *const YUndoManagerOptions) -> *mut YUndoManager {
4680 let mut o = yrs::undo::Options::default();
4681 if let Some(options) = options.as_ref() {
4682 if options.capture_timeout_millis >= 0 {
4683 o.capture_timeout_millis = options.capture_timeout_millis as u64;
4684 }
4685 };
4686 let boxed = Box::new(yrs::undo::UndoManager::with_options(o));
4687 Box::into_raw(boxed)
4688}
4689
4690#[no_mangle]
4692pub unsafe extern "C" fn yundo_manager_destroy(mgr: *mut YUndoManager) {
4693 drop(Box::from_raw(mgr));
4694}
4695
4696#[no_mangle]
4701pub unsafe extern "C" fn yundo_manager_add_origin(
4702 mgr: *mut YUndoManager,
4703 origin_len: u32,
4704 origin: *const c_char,
4705) {
4706 let mgr = mgr.as_mut().unwrap();
4707 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4708 mgr.include_origin(Origin::from(bytes));
4709}
4710
4711#[no_mangle]
4713pub unsafe extern "C" fn yundo_manager_remove_origin(
4714 mgr: *mut YUndoManager,
4715 origin_len: u32,
4716 origin: *const c_char,
4717) {
4718 let mgr = mgr.as_mut().unwrap();
4719 let bytes = std::slice::from_raw_parts(origin as *const u8, origin_len as usize);
4720 mgr.exclude_origin(Origin::from(bytes));
4721}
4722
4723#[no_mangle]
4725pub unsafe extern "C" fn yundo_manager_add_scope(
4726 mgr: *mut YUndoManager,
4727 doc: *const Doc,
4728 ytype: *const Branch,
4729) {
4730 let mgr = mgr.as_mut().unwrap();
4731 let doc = doc.as_ref().unwrap();
4732 let branch = ytype.as_ref().unwrap();
4733 mgr.expand_scope(doc, &BranchPtr::from(branch));
4734}
4735
4736#[no_mangle]
4745pub unsafe extern "C" fn yundo_manager_clear(mgr: *mut YUndoManager) {
4746 let mgr = mgr.as_mut().unwrap();
4747 mgr.clear_all();
4748}
4749
4750#[no_mangle]
4757pub unsafe extern "C" fn yundo_manager_stop(mgr: *mut YUndoManager) {
4758 let mgr = mgr.as_mut().unwrap();
4759 mgr.reset();
4760}
4761
4762#[no_mangle]
4769pub unsafe extern "C" fn yundo_manager_undo(mgr: *mut YUndoManager) -> u8 {
4770 let mgr = mgr.as_mut().unwrap();
4771
4772 if mgr.undo_blocking() {
4773 Y_TRUE
4774 } else {
4775 Y_FALSE
4776 }
4777}
4778
4779#[no_mangle]
4785pub unsafe extern "C" fn yundo_manager_redo(mgr: *mut YUndoManager) -> u8 {
4786 let mgr = mgr.as_mut().unwrap();
4787 if mgr.redo_blocking() {
4788 Y_TRUE
4789 } else {
4790 Y_FALSE
4791 }
4792}
4793
4794#[no_mangle]
4796pub unsafe extern "C" fn yundo_manager_undo_stack_len(mgr: *mut YUndoManager) -> u32 {
4797 let mgr = mgr.as_mut().unwrap();
4798 mgr.undo_stack().len() as u32
4799}
4800
4801#[no_mangle]
4803pub unsafe extern "C" fn yundo_manager_redo_stack_len(mgr: *mut YUndoManager) -> u32 {
4804 let mgr = mgr.as_mut().unwrap();
4805 mgr.redo_stack().len() as u32
4806}
4807
4808#[no_mangle]
4814pub unsafe extern "C" fn yundo_manager_observe_added(
4815 mgr: *mut YUndoManager,
4816 state: *mut c_void,
4817 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4818) -> *mut Subscription {
4819 let state = CallbackState::new(state);
4820 let mgr = mgr.as_mut().unwrap();
4821 let subscription = mgr.observe_item_added(move |_, e| {
4822 let meta_ptr = {
4823 let event = YUndoEvent::new(e);
4824 callback(state.0, &event as *const YUndoEvent);
4825 event.meta
4826 };
4827 e.meta().store(meta_ptr, Ordering::Release);
4828 });
4829 Box::into_raw(Box::new(subscription))
4830}
4831
4832#[no_mangle]
4838pub unsafe extern "C" fn yundo_manager_observe_popped(
4839 mgr: *mut YUndoManager,
4840 state: *mut c_void,
4841 callback: extern "C" fn(*mut c_void, *const YUndoEvent),
4842) -> *mut Subscription {
4843 let mgr = mgr.as_mut().unwrap();
4844 let state = CallbackState::new(state);
4845 let subscription = mgr
4846 .observe_item_popped(move |_, e| {
4847 let meta_ptr = {
4848 let event = YUndoEvent::new(e);
4849 callback(state.0, &event as *const YUndoEvent);
4850 event.meta
4851 };
4852 e.meta().store(meta_ptr, Ordering::Release);
4853 })
4854 .into();
4855 Box::into_raw(Box::new(subscription))
4856}
4857
4858pub const Y_KIND_UNDO: c_char = 0;
4859pub const Y_KIND_REDO: c_char = 1;
4860
4861#[repr(C)]
4865pub struct YUndoEvent {
4866 pub kind: c_char,
4869 pub origin: *const c_char,
4872 pub origin_len: u32,
4876 pub meta: *mut c_void,
4886}
4887
4888impl YUndoEvent {
4889 unsafe fn new(e: &yrs::undo::Event<AtomicPtr<c_void>>) -> Self {
4890 let (origin, origin_len) = if let Some(origin) = e.origin() {
4891 let bytes = origin.as_ref();
4892 let origin_len = bytes.len() as u32;
4893 let origin = bytes.as_ptr() as *const c_char;
4894 (origin, origin_len)
4895 } else {
4896 (null(), 0)
4897 };
4898 YUndoEvent {
4899 kind: match e.kind() {
4900 EventKind::Undo => Y_KIND_UNDO,
4901 EventKind::Redo => Y_KIND_REDO,
4902 },
4903 origin,
4904 origin_len,
4905 meta: e.meta().load(Ordering::Acquire),
4906 }
4907 }
4908}
4909
4910#[no_mangle]
4914pub unsafe extern "C" fn ytype_kind(branch: *const Branch) -> i8 {
4915 if let Some(branch) = branch.as_ref() {
4916 match branch.type_ref() {
4917 TypeRef::Array => Y_ARRAY,
4918 TypeRef::Map => Y_MAP,
4919 TypeRef::Text => Y_TEXT,
4920 TypeRef::XmlElement(_) => Y_XML_ELEM,
4921 TypeRef::XmlText => Y_XML_TEXT,
4922 TypeRef::XmlFragment => Y_XML_FRAG,
4923 TypeRef::SubDoc => Y_DOC,
4924 TypeRef::WeakLink(_) => Y_WEAK_LINK,
4925 TypeRef::XmlHook => 0,
4926 TypeRef::Undefined => 0,
4927 }
4928 } else {
4929 0
4930 }
4931}
4932
4933pub const Y_EVENT_PATH_KEY: c_char = 1;
4935
4936pub const Y_EVENT_PATH_INDEX: c_char = 2;
4938
4939#[repr(C)]
4947pub struct YPathSegment {
4948 pub tag: c_char,
4956
4957 pub value: YPathSegmentCase,
4960}
4961
4962impl From<PathSegment> for YPathSegment {
4963 fn from(ps: PathSegment) -> Self {
4964 match ps {
4965 PathSegment::Key(key) => {
4966 let key = CString::new(key.as_ref()).unwrap().into_raw() as *const _;
4967 YPathSegment {
4968 tag: Y_EVENT_PATH_KEY,
4969 value: YPathSegmentCase { key },
4970 }
4971 }
4972 PathSegment::Index(index) => YPathSegment {
4973 tag: Y_EVENT_PATH_INDEX,
4974 value: YPathSegmentCase {
4975 index: index as u32,
4976 },
4977 },
4978 }
4979 }
4980}
4981
4982impl Drop for YPathSegment {
4983 fn drop(&mut self) {
4984 if self.tag == Y_EVENT_PATH_KEY {
4985 unsafe {
4986 ystring_destroy(self.value.key as *mut _);
4987 }
4988 }
4989 }
4990}
4991
4992#[repr(C)]
4993pub union YPathSegmentCase {
4994 pub key: *const c_char,
4995 pub index: u32,
4996}
4997
4998pub const Y_EVENT_CHANGE_ADD: u8 = 1;
5001
5002pub const Y_EVENT_CHANGE_DELETE: u8 = 2;
5005
5006pub const Y_EVENT_CHANGE_RETAIN: u8 = 3;
5009
5010#[repr(C)]
5026pub struct YEventChange {
5027 pub tag: u8,
5037
5038 pub len: u32,
5041
5042 pub values: *const YOutput,
5045}
5046
5047impl<'a> From<&'a Change> for YEventChange {
5048 fn from(change: &'a Change) -> Self {
5049 match change {
5050 Change::Added(values) => {
5051 let out: Vec<_> = values
5052 .into_iter()
5053 .map(|v| YOutput::from(v.clone()))
5054 .collect();
5055 let len = out.len() as u32;
5056 let out = out.into_boxed_slice();
5057 let values = Box::into_raw(out) as *mut _;
5058
5059 YEventChange {
5060 tag: Y_EVENT_CHANGE_ADD,
5061 len,
5062 values,
5063 }
5064 }
5065 Change::Removed(len) => YEventChange {
5066 tag: Y_EVENT_CHANGE_DELETE,
5067 len: *len as u32,
5068 values: null(),
5069 },
5070 Change::Retain(len) => YEventChange {
5071 tag: Y_EVENT_CHANGE_RETAIN,
5072 len: *len as u32,
5073 values: null(),
5074 },
5075 }
5076 }
5077}
5078
5079impl Drop for YEventChange {
5080 fn drop(&mut self) {
5081 if self.tag == Y_EVENT_CHANGE_ADD {
5082 unsafe {
5083 let len = self.len as usize;
5084 let values = Vec::from_raw_parts(self.values as *mut YOutput, len, len);
5085 drop(values);
5086 }
5087 }
5088 }
5089}
5090
5091#[repr(C)]
5110pub struct YDeltaOut {
5111 pub tag: u8,
5121
5122 pub len: u32,
5125
5126 pub attributes_len: u32,
5128
5129 pub attributes: *mut YDeltaAttr,
5132
5133 pub insert: *mut YOutput,
5136}
5137
5138impl YDeltaOut {
5139 fn insert(value: &Out, attrs: &Option<Box<Attrs>>) -> Self {
5140 let insert = Box::into_raw(Box::new(YOutput::from(value.clone())));
5141 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5142 let len = attrs.len() as u32;
5143 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5144 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5145 (len, attrs)
5146 } else {
5147 (0, null_mut())
5148 };
5149
5150 YDeltaOut {
5151 tag: Y_EVENT_CHANGE_ADD,
5152 len: 1,
5153 insert,
5154 attributes_len,
5155 attributes,
5156 }
5157 }
5158
5159 fn retain(len: u32, attrs: &Option<Box<Attrs>>) -> Self {
5160 let (attributes_len, attributes) = if let Some(attrs) = attrs {
5161 let len = attrs.len() as u32;
5162 let attrs: Vec<_> = attrs.iter().map(|(k, v)| YDeltaAttr::new(k, v)).collect();
5163 let attrs = Box::into_raw(attrs.into_boxed_slice()) as *mut _;
5164 (len, attrs)
5165 } else {
5166 (0, null_mut())
5167 };
5168 YDeltaOut {
5169 tag: Y_EVENT_CHANGE_RETAIN,
5170 len,
5171 insert: null_mut(),
5172 attributes_len,
5173 attributes,
5174 }
5175 }
5176
5177 fn delete(len: u32) -> Self {
5178 YDeltaOut {
5179 tag: Y_EVENT_CHANGE_DELETE,
5180 len,
5181 insert: null_mut(),
5182 attributes_len: 0,
5183 attributes: null_mut(),
5184 }
5185 }
5186}
5187
5188impl<'a> From<&'a Delta> for YDeltaOut {
5189 fn from(d: &Delta) -> Self {
5190 match d {
5191 Delta::Inserted(value, attrs) => YDeltaOut::insert(value, attrs),
5192 Delta::Retain(len, attrs) => YDeltaOut::retain(*len, attrs),
5193 Delta::Deleted(len) => YDeltaOut::delete(*len),
5194 }
5195 }
5196}
5197
5198impl Drop for YDeltaOut {
5199 fn drop(&mut self) {
5200 unsafe {
5201 if !self.attributes.is_null() {
5202 let len = self.attributes_len as usize;
5203 drop(Vec::from_raw_parts(self.attributes, len, len));
5204 }
5205 if !self.insert.is_null() {
5206 drop(Box::from_raw(self.insert));
5207 }
5208 }
5209 }
5210}
5211
5212#[repr(C)]
5214pub struct YDeltaAttr {
5215 pub key: *const c_char,
5217 pub value: YOutput,
5219}
5220
5221impl YDeltaAttr {
5222 fn new(k: &Arc<str>, v: &Any) -> Self {
5223 let key = CString::new(k.as_ref()).unwrap().into_raw() as *const _;
5224 let value = YOutput::from(v);
5225 YDeltaAttr { key, value }
5226 }
5227}
5228
5229impl Drop for YDeltaAttr {
5230 fn drop(&mut self) {
5231 unsafe { ystring_destroy(self.key as *mut _) }
5232 }
5233}
5234
5235#[repr(C)]
5250pub struct YDeltaIn {
5251 pub tag: u8,
5261
5262 pub len: u32,
5265
5266 pub attributes: *const YInput,
5269
5270 pub insert: *const YInput,
5273}
5274
5275impl YDeltaIn {
5276 fn as_input(&self) -> Delta<YInput> {
5277 match self.tag {
5278 Y_EVENT_CHANGE_RETAIN => {
5279 let attrs = if self.attributes.is_null() {
5280 None
5281 } else {
5282 let attrs = unsafe { self.attributes.read() };
5283 map_attrs(attrs.into()).map(Box::new)
5284 };
5285 Delta::Retain(self.len, attrs)
5286 }
5287 Y_EVENT_CHANGE_DELETE => Delta::Deleted(self.len),
5288 Y_EVENT_CHANGE_ADD => {
5289 let attrs = if self.attributes.is_null() {
5290 None
5291 } else {
5292 let attrs = unsafe { self.attributes.read() };
5293 map_attrs(attrs.into()).map(Box::new)
5294 };
5295 let input = unsafe { self.insert.read() };
5296 Delta::Inserted(input, attrs)
5297 }
5298 tag => panic!("YDelta tag identifier is of unknown type: {}", tag),
5299 }
5300 }
5301}
5302
5303pub const Y_EVENT_KEY_CHANGE_ADD: c_char = 4;
5306
5307pub const Y_EVENT_KEY_CHANGE_DELETE: c_char = 5;
5310
5311pub const Y_EVENT_KEY_CHANGE_UPDATE: c_char = 6;
5314
5315#[repr(C)]
5328pub struct YEventKeyChange {
5329 pub key: *const c_char,
5331 pub tag: c_char,
5341
5342 pub old_value: *const YOutput,
5344
5345 pub new_value: *const YOutput,
5347}
5348
5349impl YEventKeyChange {
5350 fn new(key: &str, change: &EntryChange) -> Self {
5351 let key = CString::new(key).unwrap().into_raw() as *const _;
5352 match change {
5353 EntryChange::Inserted(new) => YEventKeyChange {
5354 key,
5355 tag: Y_EVENT_KEY_CHANGE_ADD,
5356 old_value: null(),
5357 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5358 },
5359 EntryChange::Updated(old, new) => YEventKeyChange {
5360 key,
5361 tag: Y_EVENT_KEY_CHANGE_UPDATE,
5362 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5363 new_value: Box::into_raw(Box::new(YOutput::from(new.clone()))),
5364 },
5365 EntryChange::Removed(old) => YEventKeyChange {
5366 key,
5367 tag: Y_EVENT_KEY_CHANGE_DELETE,
5368 old_value: Box::into_raw(Box::new(YOutput::from(old.clone()))),
5369 new_value: null(),
5370 },
5371 }
5372 }
5373}
5374
5375impl Drop for YEventKeyChange {
5376 fn drop(&mut self) {
5377 unsafe {
5378 ystring_destroy(self.key as *mut _);
5379 youtput_destroy(self.old_value as *mut _);
5380 youtput_destroy(self.new_value as *mut _);
5381 }
5382 }
5383}
5384
5385trait BranchPointable {
5386 fn into_raw_branch(self) -> *mut Branch;
5387 fn from_raw_branch(branch: *const Branch) -> Self;
5388}
5389
5390impl<T> BranchPointable for T
5391where
5392 T: AsRef<Branch> + From<BranchPtr>,
5393{
5394 fn into_raw_branch(self) -> *mut Branch {
5395 let branch_ref = self.as_ref();
5396 branch_ref as *const Branch as *mut Branch
5397 }
5398
5399 fn from_raw_branch(branch: *const Branch) -> Self {
5400 let b = unsafe { branch.as_ref().unwrap() };
5401 let branch_ref = BranchPtr::from(b);
5402 T::from(branch_ref)
5403 }
5404}
5405
5406#[repr(transparent)]
5417pub struct YStickyIndex(StickyIndex);
5418
5419impl From<StickyIndex> for YStickyIndex {
5420 #[inline(always)]
5421 fn from(value: StickyIndex) -> Self {
5422 YStickyIndex(value)
5423 }
5424}
5425
5426#[no_mangle]
5428pub unsafe extern "C" fn ysticky_index_destroy(pos: *mut YStickyIndex) {
5429 drop(Box::from_raw(pos))
5430}
5431
5432#[no_mangle]
5436pub unsafe extern "C" fn ysticky_index_assoc(pos: *const YStickyIndex) -> i8 {
5437 let pos = pos.as_ref().unwrap();
5438 match pos.0.assoc {
5439 Assoc::After => 0,
5440 Assoc::Before => -1,
5441 }
5442}
5443
5444#[no_mangle]
5451pub unsafe extern "C" fn ysticky_index_from_index(
5452 branch: *const Branch,
5453 txn: *mut Transaction,
5454 index: u32,
5455 assoc: i8,
5456) -> *mut YStickyIndex {
5457 assert!(!branch.is_null());
5458 assert!(!txn.is_null());
5459
5460 let branch = BranchPtr::from_raw_branch(branch);
5461 let txn = txn.as_mut().unwrap();
5462 let index = index as u32;
5463 let assoc = if assoc >= 0 {
5464 Assoc::After
5465 } else {
5466 Assoc::Before
5467 };
5468
5469 if let Some(txn) = txn.as_mut() {
5470 if let Some(pos) = StickyIndex::at(txn, branch, index, assoc) {
5471 Box::into_raw(Box::new(YStickyIndex(pos)))
5472 } else {
5473 null_mut()
5474 }
5475 } else {
5476 panic!("ysticky_index_from_index requires a read-write transaction");
5477 }
5478}
5479
5480#[no_mangle]
5483pub unsafe extern "C" fn ysticky_index_encode(
5484 pos: *const YStickyIndex,
5485 len: *mut u32,
5486) -> *mut c_char {
5487 let pos = pos.as_ref().unwrap();
5488 let binary = pos.0.encode_v1().into_boxed_slice();
5489 *len = binary.len() as u32;
5490 Box::into_raw(binary) as *mut c_char
5491}
5492
5493#[no_mangle]
5496pub unsafe extern "C" fn ysticky_index_decode(
5497 binary: *const c_char,
5498 len: u32,
5499) -> *mut YStickyIndex {
5500 let slice = std::slice::from_raw_parts(binary as *const u8, len as usize);
5501 if let Ok(pos) = StickyIndex::decode_v1(slice) {
5502 Box::into_raw(Box::new(YStickyIndex(pos)))
5503 } else {
5504 null_mut()
5505 }
5506}
5507
5508#[no_mangle]
5512pub unsafe extern "C" fn ysticky_index_to_json(pos: *const YStickyIndex) -> *mut c_char {
5513 let pos = pos.as_ref().unwrap();
5514 let json = match serde_json::to_string(&pos.0) {
5515 Ok(json) => json,
5516 Err(_) => return null_mut(),
5517 };
5518 CString::new(json).unwrap().into_raw()
5519}
5520
5521#[no_mangle]
5530pub unsafe extern "C" fn ysticky_index_from_json(json: *const c_char) -> *mut YStickyIndex {
5531 let cstr = CStr::from_ptr(json);
5532 let json = match cstr.to_str() {
5533 Ok(json) => json,
5534 Err(_) => return null_mut(),
5535 };
5536 match serde_json::from_str(json) {
5537 Ok(pos) => Box::into_raw(Box::new(YStickyIndex(pos))),
5538 Err(_) => null_mut(),
5539 }
5540}
5541
5542#[no_mangle]
5548pub unsafe extern "C" fn ysticky_index_read(
5549 pos: *const YStickyIndex,
5550 txn: *const Transaction,
5551 out_branch: *mut *mut Branch,
5552 out_index: *mut u32,
5553) {
5554 let pos = pos.as_ref().unwrap();
5555 let txn = txn.as_ref().unwrap();
5556
5557 if let Some(abs) = pos.0.get_offset(txn) {
5558 *out_branch = abs.branch.as_ref() as *const Branch as *mut Branch;
5559 *out_index = abs.index as u32;
5560 }
5561}
5562
5563pub type Weak = LinkSource;
5564
5565#[no_mangle]
5566pub unsafe extern "C" fn yweak_destroy(weak: *const Weak) {
5567 drop(Arc::from_raw(weak));
5568}
5569
5570#[no_mangle]
5571pub unsafe extern "C" fn yweak_deref(
5572 map_link: *const Branch,
5573 txn: *const Transaction,
5574) -> *mut YOutput {
5575 assert!(!map_link.is_null());
5576 assert!(!txn.is_null());
5577
5578 let txn = txn.as_ref().unwrap();
5579 let weak: WeakRef<MapRef> = WeakRef::from_raw_branch(map_link);
5580 if let Some(value) = weak.try_deref_value(txn) {
5581 Box::into_raw(Box::new(YOutput::from(value)))
5582 } else {
5583 null_mut()
5584 }
5585}
5586
5587#[no_mangle]
5588pub unsafe extern "C" fn yweak_read(
5589 text_link: *const Branch,
5590 txn: *const Transaction,
5591 out_branch: *mut *mut Branch,
5592 out_start_index: *mut u32,
5593 out_end_index: *mut u32,
5594) {
5595 assert!(!text_link.is_null());
5596 assert!(!txn.is_null());
5597
5598 let txn = txn.as_ref().unwrap();
5599 let weak: WeakRef<BranchPtr> = WeakRef::from_raw_branch(text_link);
5600 if let Some(id) = weak.start_id() {
5601 let start = StickyIndex::from_id(*id, Assoc::After);
5603 assert!(weak.end_id() != None);
5604 let end = StickyIndex::from_id(*weak.end_id().unwrap(), Assoc::After);
5605 if let Some(start_pos) = start.get_offset(txn) {
5606 *out_branch = start_pos.branch.as_ref() as *const Branch as *mut Branch;
5607 *out_start_index = start_pos.index as u32;
5608 if let Some(end_pos) = end.get_offset(txn) {
5609 assert!(*out_branch == end_pos.branch.as_ref() as *const Branch as *mut Branch);
5610 *out_end_index = end_pos.index as u32;
5611 }
5612 }
5613 } else {
5614 assert!(weak.end_id() == None); *out_start_index = 0; *out_end_index = 0; }
5619}
5620
5621#[no_mangle]
5622pub unsafe extern "C" fn yweak_iter(
5623 array_link: *const Branch,
5624 txn: *const Transaction,
5625) -> *mut WeakIter {
5626 assert!(!array_link.is_null());
5627 assert!(!txn.is_null());
5628
5629 let txn = txn.as_ref().unwrap();
5630 let weak: WeakRef<ArrayRef> = WeakRef::from_raw_branch(array_link);
5631 let iter: NativeUnquote<'static, Transaction> = std::mem::transmute(weak.unquote(txn));
5632
5633 Box::into_raw(Box::new(WeakIter(iter)))
5634}
5635
5636#[no_mangle]
5637pub unsafe extern "C" fn yweak_iter_destroy(iter: *mut WeakIter) {
5638 drop(Box::from_raw(iter))
5639}
5640
5641#[no_mangle]
5642pub unsafe extern "C" fn yweak_iter_next(iter: *mut WeakIter) -> *mut YOutput {
5643 assert!(!iter.is_null());
5644 let iter = iter.as_mut().unwrap();
5645
5646 if let Some(value) = iter.0.next() {
5647 Box::into_raw(Box::new(YOutput::from(value)))
5648 } else {
5649 null_mut()
5650 }
5651}
5652
5653#[no_mangle]
5654pub unsafe extern "C" fn yweak_string(
5655 text_link: *const Branch,
5656 txn: *const Transaction,
5657) -> *mut c_char {
5658 assert!(!text_link.is_null());
5659 assert!(!txn.is_null());
5660
5661 let txn = txn.as_ref().unwrap();
5662 let weak: WeakRef<TextRef> = WeakRef::from_raw_branch(text_link);
5663
5664 let str = weak.get_string(txn);
5665 CString::new(str).unwrap().into_raw()
5666}
5667
5668#[no_mangle]
5669pub unsafe extern "C" fn yweak_xml_string(
5670 xml_text_link: *const Branch,
5671 txn: *const Transaction,
5672) -> *mut c_char {
5673 assert!(!xml_text_link.is_null());
5674 assert!(!txn.is_null());
5675
5676 let txn = txn.as_ref().unwrap();
5677 let weak: WeakRef<XmlTextRef> = WeakRef::from_raw_branch(xml_text_link);
5678
5679 let str = weak.get_string(txn);
5680 CString::new(str).unwrap().into_raw()
5681}
5682
5683#[no_mangle]
5688pub unsafe extern "C" fn yweak_observe(
5689 weak: *const Branch,
5690 state: *mut c_void,
5691 cb: extern "C" fn(*mut c_void, *const YWeakLinkEvent),
5692) -> *mut Subscription {
5693 assert!(!weak.is_null());
5694
5695 let state = CallbackState::new(state);
5696 let txt: WeakRef<BranchPtr> = WeakRef::from_raw_branch(weak);
5697 let subscription = txt.observe(move |txn, e| {
5698 let e = YWeakLinkEvent::new(e, txn);
5699 cb(state.0, &e as *const YWeakLinkEvent);
5700 });
5701 Box::into_raw(Box::new(subscription))
5702}
5703
5704#[no_mangle]
5705pub unsafe extern "C" fn ymap_link(
5706 map: *const Branch,
5707 txn: *const Transaction,
5708 key: *const c_char,
5709) -> *const Weak {
5710 assert!(!map.is_null());
5711 assert!(!txn.is_null());
5712
5713 let txn = txn.as_ref().unwrap();
5714 let map = MapRef::from_raw_branch(map);
5715 let key = CStr::from_ptr(key).to_str().unwrap();
5716 if let Some(weak) = map.link(txn, key) {
5717 let source = weak.source();
5718 Arc::into_raw(source.clone())
5719 } else {
5720 null()
5721 }
5722}
5723
5724#[no_mangle]
5725pub unsafe extern "C" fn ytext_quote(
5726 text: *const Branch,
5727 txn: *mut Transaction,
5728 start_index: *mut u32,
5729 end_index: *mut u32,
5730 start_exclusive: i8,
5731 end_exclusive: i8,
5732) -> *const Weak {
5733 assert!(!text.is_null());
5734 assert!(!txn.is_null());
5735
5736 let text = TextRef::from_raw_branch(text);
5737 let txn = txn.as_mut().unwrap();
5738 let txn = txn
5739 .as_mut()
5740 .expect("provided transaction was not writeable");
5741
5742 let start_index = start_index.as_ref().cloned();
5743 let end_index = end_index.as_ref().cloned();
5744 let range = ExplicitRange {
5745 start_index,
5746 end_index,
5747 start_exclusive,
5748 end_exclusive,
5749 };
5750 if let Ok(weak) = text.quote(txn, range) {
5751 let source = weak.source();
5752 Arc::into_raw(source.clone())
5753 } else {
5754 null()
5755 }
5756}
5757
5758#[no_mangle]
5759pub unsafe extern "C" fn yarray_quote(
5760 array: *const Branch,
5761 txn: *mut Transaction,
5762 start_index: *mut u32,
5763 end_index: *mut u32,
5764 start_exclusive: i8,
5765 end_exclusive: i8,
5766) -> *const Weak {
5767 assert!(!array.is_null());
5768 assert!(!txn.is_null());
5769
5770 let array = ArrayRef::from_raw_branch(array);
5771 let txn = txn.as_mut().unwrap();
5772 let txn = txn
5773 .as_mut()
5774 .expect("provided transaction was not writeable");
5775
5776 let start_index = start_index.as_ref().cloned();
5777 let end_index = end_index.as_ref().cloned();
5778 let range = ExplicitRange {
5779 start_index,
5780 end_index,
5781 start_exclusive,
5782 end_exclusive,
5783 };
5784 if let Ok(weak) = array.quote(txn, range) {
5785 let source = weak.source();
5786 Arc::into_raw(source.clone())
5787 } else {
5788 null()
5789 }
5790}
5791
5792struct ExplicitRange {
5793 start_index: Option<u32>,
5794 end_index: Option<u32>,
5795 start_exclusive: i8,
5796 end_exclusive: i8,
5797}
5798
5799impl RangeBounds<u32> for ExplicitRange {
5800 fn start_bound(&self) -> Bound<&u32> {
5801 match (&self.start_index, self.start_exclusive) {
5802 (None, _) => Bound::Unbounded,
5803 (Some(i), 0) => Bound::Included(i),
5804 (Some(i), _) => Bound::Excluded(i),
5805 }
5806 }
5807
5808 fn end_bound(&self) -> Bound<&u32> {
5809 match (&self.end_index, self.end_exclusive) {
5810 (None, _) => Bound::Unbounded,
5811 (Some(i), 0) => Bound::Included(i),
5812 (Some(i), _) => Bound::Excluded(i),
5813 }
5814 }
5815}
5816
5817#[repr(C)]
5825pub struct YBranchId {
5826 pub client_or_len: i64,
5829 pub variant: YBranchIdVariant,
5830}
5831
5832#[repr(C)]
5833pub union YBranchIdVariant {
5834 pub clock: u32,
5836 pub name: *const u8,
5841}
5842
5843#[no_mangle]
5846pub unsafe extern "C" fn ybranch_id(branch: *const Branch) -> YBranchId {
5847 let branch = branch.as_ref().unwrap();
5848 match branch.id() {
5849 BranchID::Nested(id) => YBranchId {
5850 client_or_len: id.client.get() as i64,
5851 variant: YBranchIdVariant { clock: id.clock },
5852 },
5853 BranchID::Root(name) => {
5854 let len = -(name.len() as i64);
5855 YBranchId {
5856 client_or_len: len,
5857 variant: YBranchIdVariant {
5858 name: name.as_ptr(),
5859 },
5860 }
5861 }
5862 }
5863}
5864
5865#[no_mangle]
5871pub unsafe extern "C" fn ybranch_get(
5872 branch_id: *const YBranchId,
5873 txn: *mut Transaction,
5874) -> *mut Branch {
5875 let txn = txn.as_ref().unwrap();
5876 let branch_id = branch_id.as_ref().unwrap();
5877 let client_or_len = branch_id.client_or_len;
5878 let ptr = if client_or_len >= 0 {
5879 BranchID::get_nested(
5880 txn,
5881 &ID::new(ClientID::new(client_or_len as u64), branch_id.variant.clock),
5882 )
5883 } else {
5884 let name = std::slice::from_raw_parts(branch_id.variant.name, (-client_or_len) as usize);
5885 BranchID::get_root(txn, std::str::from_utf8_unchecked(name))
5886 };
5887
5888 match ptr {
5889 None => null_mut(),
5890 Some(branch_ptr) => branch_ptr.into_raw_branch(),
5891 }
5892}
5893
5894#[no_mangle]
5898pub unsafe extern "C" fn ybranch_alive(branch: *mut Branch) -> u8 {
5899 if branch.is_null() {
5900 Y_FALSE
5901 } else {
5902 let branch = BranchPtr::from_raw_branch(branch);
5903 if branch.is_deleted() {
5904 Y_FALSE
5905 } else {
5906 Y_TRUE
5907 }
5908 }
5909}
5910
5911#[no_mangle]
5918pub unsafe extern "C" fn ybranch_json(branch: *mut Branch, txn: *mut Transaction) -> *mut c_char {
5919 if branch.is_null() {
5920 std::ptr::null_mut()
5921 } else {
5922 let txn = txn.as_ref().unwrap();
5923 let branch_ref = BranchPtr::from_raw_branch(branch);
5924 let any = match branch_ref.type_ref() {
5925 TypeRef::Array => ArrayRef::from_raw_branch(branch).to_json(txn),
5926 TypeRef::Map => MapRef::from_raw_branch(branch).to_json(txn),
5927 TypeRef::Text => TextRef::from_raw_branch(branch).get_string(txn).into(),
5928 TypeRef::XmlElement(_) => XmlElementRef::from_raw_branch(branch)
5929 .get_string(txn)
5930 .into(),
5931 TypeRef::XmlFragment => XmlFragmentRef::from_raw_branch(branch)
5932 .get_string(txn)
5933 .into(),
5934 TypeRef::XmlText => XmlTextRef::from_raw_branch(branch).get_string(txn).into(),
5935 TypeRef::SubDoc | TypeRef::XmlHook | TypeRef::WeakLink(_) | TypeRef::Undefined => {
5936 return std::ptr::null_mut()
5937 }
5938 };
5939 let json = match serde_json::to_string(&any) {
5940 Ok(json) => json,
5941 Err(_) => return std::ptr::null_mut(),
5942 };
5943 CString::new(json).unwrap().into_raw()
5944 }
5945}