Skip to main content

fig_sys/
lib.rs

1//! Low-level FFI bindings for fig's C ABI, plus the build script that compiles
2//! and links the native `libfig.a`.
3//!
4//! This is the `-sys` layer: raw `extern "C"` functions, `#[repr(C)]` type
5//! mirrors, and status/format constants — nothing else. The safe, ergonomic
6//! API (and serde/derive integration) lives in the `fig` crate, which depends
7//! on this one. Direct use is `unsafe` and unstable across ABI-version bumps.
8#![allow(non_camel_case_types)]
9
10use std::os::raw::c_int;
11
12/// A fig C ABI status code, as a transparent wrapper over the raw `c_int` the
13/// ABI returns — deliberately *not* a Rust `enum`.
14///
15/// A fieldless `#[repr(C)]` enum returned by value from an `extern "C"` function
16/// is undefined behavior the instant the callee returns a discriminant the enum
17/// does not list, and fig's status set is allowed to grow after 1.0. The newtype
18/// preserves any code unchanged; compare against the associated constants and
19/// route unrecognized values through a fallback (the `fig` crate does this in
20/// its `Error::from_status`).
21#[repr(transparent)]
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
23pub struct FigStatus(pub c_int);
24
25#[allow(dead_code)]
26impl FigStatus {
27    pub const OK: c_int = 0;
28    pub const INVALID_ARGUMENT: c_int = 1;
29    pub const PARSE_ERROR: c_int = 2;
30    pub const OUT_OF_MEMORY: c_int = 3;
31    pub const UNSUPPORTED_FORMAT: c_int = 4;
32    pub const NOT_FOUND: c_int = 5;
33    pub const INTERNAL_ERROR: c_int = 255;
34}
35
36#[repr(C)]
37#[derive(Clone, Copy, Debug, Eq, PartialEq)]
38pub enum FigFormat {
39    Json = 1,
40    Jsonc = 2,
41    Yaml = 3,
42    Toml = 4,
43    Zon = 5,
44    // `Xml = 6` in the C ABI is reader-only and has no writable `Format`
45    // variant, so it is intentionally omitted here; the discriminant gap is
46    // deliberate to keep JSON5 at its stable ABI value.
47    Json5 = 7,
48    // The native `fig` authoring dialect. Appended, same reasoning as JSON5.
49    Fig = 8,
50}
51
52pub enum FigDocument {}
53
54pub type FigNodeId = u32;
55
56/// Sentinel for "no such node", matching `FIG_NODE_NONE` in `fig.h`.
57pub const FIG_NODE_NONE: FigNodeId = 0xFFFF_FFFF;
58
59#[repr(C)]
60#[derive(Clone, Copy, Debug, Eq, PartialEq)]
61#[allow(dead_code)]
62pub enum FigNodeKind {
63    Invalid = -1,
64    Null = 0,
65    Bool = 1,
66    Int = 2,
67    Float = 3,
68    String = 4,
69    Sequence = 5,
70    Mapping = 6,
71    Keyvalue = 7,
72    Alias = 8,
73}
74
75impl FigNodeKind {
76    /// Map the raw `c_int` returned by `fig_node_kind` onto a `FigNodeKind`.
77    /// Unknown / future kinds collapse to [`FigNodeKind::Invalid`] rather than
78    /// being reinterpreted as an out-of-range enum value — which, for a value
79    /// returned by an `extern "C"` function into a Rust enum, is undefined
80    /// behavior. This is the only place a raw kind crosses into the enum.
81    pub fn from_c(raw: c_int) -> Self {
82        match raw {
83            0 => FigNodeKind::Null,
84            1 => FigNodeKind::Bool,
85            2 => FigNodeKind::Int,
86            3 => FigNodeKind::Float,
87            4 => FigNodeKind::String,
88            5 => FigNodeKind::Sequence,
89            6 => FigNodeKind::Mapping,
90            7 => FigNodeKind::Keyvalue,
91            8 => FigNodeKind::Alias,
92            _ => FigNodeKind::Invalid,
93        }
94    }
95}
96
97/// A caller-allocated parse diagnostic. Mirrors `FigError` in `fig.h`. Lead with
98/// `size = size_of::<FigError>()`: the library writes only the fields `size`
99/// covers, so it can gain fields in a later release without breaking this layout.
100/// `byte_offset`/`line`/`column` are 0 when unknown (always 0 in this release —
101/// offset plumbing is a planned core follow-up). `message` is NUL-terminated and
102/// truncated to fit; `message_len` excludes the NUL.
103#[repr(C)]
104#[derive(Clone, Copy)]
105pub struct FigError {
106    pub size: u32,
107    pub code: c_int,
108    pub byte_offset: usize,
109    pub line: u32,
110    pub column: u32,
111    pub message_len: usize,
112    pub message: [u8; 256],
113}
114
115impl FigError {
116    /// A zeroed struct with `size` set, ready to pass to `fig_parse_ex`.
117    pub fn new() -> Self {
118        FigError {
119            size: std::mem::size_of::<FigError>() as u32,
120            code: 0,
121            byte_offset: 0,
122            line: 0,
123            column: 0,
124            message_len: 0,
125            message: [0; 256],
126        }
127    }
128}
129
130unsafe extern "C" {
131    pub fn fig_version() -> u32;
132    pub fn fig_version_string() -> *const std::os::raw::c_char;
133    pub fn fig_format_capabilities(format: c_int) -> u32;
134
135    // Declared for ABI-mirror completeness; the binding parses via `fig_parse_ex`
136    // (richer errors), so this plain entry point is not called from Rust.
137    #[allow(dead_code)]
138    pub fn fig_parse(
139        input: *const u8,
140        input_len: usize,
141        format: c_int,
142        out_doc: *mut *mut FigDocument,
143    ) -> FigStatus;
144
145    pub fn fig_parse_ex(
146        input: *const u8,
147        input_len: usize,
148        format: c_int,
149        out_doc: *mut *mut FigDocument,
150        out_err: *mut FigError,
151    ) -> FigStatus;
152
153    pub fn fig_document_destroy(doc: *mut FigDocument);
154
155    pub fn fig_document_serialize(
156        doc: *mut FigDocument,
157        format: c_int,
158        options: *const FigSerializeOptions,
159        out_ptr: *mut *const u8,
160        out_len: *mut usize,
161    ) -> FigStatus;
162}
163
164// Read traversal — consumed by `Document::to_value` and the serde deserializer.
165unsafe extern "C" {
166    pub fn fig_document_root(doc: *const FigDocument) -> FigNodeId;
167    // Returns the raw kind as `c_int`, not `FigNodeKind`: decoding it directly
168    // into the enum would be UB if the core returned an unlisted value. Callers
169    // go through `FigNodeKind::from_c`.
170    pub fn fig_node_kind(doc: *const FigDocument, node: FigNodeId) -> c_int;
171    pub fn fig_node_first_child(doc: *const FigDocument, node: FigNodeId) -> FigNodeId;
172    pub fn fig_node_next_sibling(doc: *const FigDocument, node: FigNodeId) -> FigNodeId;
173    pub fn fig_node_child_count(doc: *const FigDocument, node: FigNodeId) -> usize;
174    pub fn fig_keyvalue_key(doc: *const FigDocument, node: FigNodeId) -> FigNodeId;
175    pub fn fig_keyvalue_value(doc: *const FigDocument, node: FigNodeId) -> FigNodeId;
176
177    pub fn fig_node_bool(doc: *const FigDocument, node: FigNodeId, out: *mut bool) -> bool;
178    pub fn fig_node_number(
179        doc: *const FigDocument,
180        node: FigNodeId,
181        out_ptr: *mut *const u8,
182        out_len: *mut usize,
183    ) -> bool;
184    pub fn fig_node_string(
185        doc: *const FigDocument,
186        node: FigNodeId,
187        out_ptr: *mut *const u8,
188        out_len: *mut usize,
189    ) -> bool;
190    pub fn fig_node_extended(
191        doc: *const FigDocument,
192        node: FigNodeId,
193        out_kind: *mut c_int,
194        out_ptr: *mut *const u8,
195        out_len: *mut usize,
196    ) -> bool;
197}
198
199// ---- value construction + serialization ----
200
201pub enum FigValue {}
202
203/// A `key: value` entry for `fig_value_map`. Mirrors `FigKeyValue` in `fig.h`.
204#[repr(C)]
205#[derive(Clone, Copy, Debug)]
206pub struct FigKeyValue {
207    pub key: FigNodeId,
208    pub value: FigNodeId,
209}
210
211/// Output style for `fig_value_serialize_opts`/`fig_document_serialize`. Mirrors
212/// `FigSerializeOptions` in `fig.h`. ALL trailing fields are declared explicitly
213/// (not left to struct padding): with `size = size_of` the core reads every byte
214/// up to `size`, so an undeclared `strip_comments`/`lossless` would otherwise be
215/// read out of uninitialized padding.
216#[repr(C)]
217#[derive(Clone, Copy, Debug)]
218pub struct FigSerializeOptions {
219    /// Set to `size_of::<FigSerializeOptions>()`. Version tag for the struct:
220    /// the core reads a field only when `size` covers it, so fields can be
221    /// appended without breaking this layout. See `FigSerializeOptions` in `fig.h`.
222    pub size: u32,
223    pub pretty: u8,
224    pub indent: u8,
225    pub strip_comments: u8,
226    pub lossless: u8,
227    pub width: u16,
228    /// fig-format fragments only: nonzero renders a container root as inline
229    /// flow (`[a, b]` / `{ k = v }`). Set by the editors' splice path (see
230    /// `value_text`); not exposed on the public `SerializeOptions` — inline is
231    /// a property of *where* the text goes, not a caller style preference.
232    pub flow: u8,
233}
234
235/// One lossy event from `fig_*_diagnose`, pulled by index via `fig_*_warning`.
236/// Caller-allocated; lead with `size = size_of::<FigWarning>()` (same policy as
237/// `FigSerializeOptions`/`FigError`). `path`/`note` are NOT NUL-terminated and
238/// borrow the producing handle's diagnostics arena (valid until the next
239/// diagnose on it or its destroy) — copy them out before then. Mirrors
240/// `FigWarning` in `fig.h`.
241#[repr(C)]
242#[derive(Clone, Copy)]
243pub struct FigWarning {
244    pub size: u32,
245    pub code: c_int,
246    pub cause: c_int,
247    pub path: *const u8,
248    pub path_len: usize,
249    pub note: *const u8,
250    pub note_len: usize,
251}
252
253impl FigWarning {
254    /// A zeroed struct with `size` set, ready to pass to a `fig_*_warning` call.
255    pub fn new() -> Self {
256        FigWarning {
257            size: std::mem::size_of::<FigWarning>() as u32,
258            code: 0,
259            cause: 0,
260            path: std::ptr::null(),
261            path_len: 0,
262            note: std::ptr::null(),
263            note_len: 0,
264        }
265    }
266}
267
268unsafe extern "C" {
269    pub fn fig_value_create(out_value: *mut *mut FigValue) -> FigStatus;
270    pub fn fig_value_destroy(value: *mut FigValue);
271
272    pub fn fig_value_null(value: *mut FigValue, out_id: *mut FigNodeId) -> FigStatus;
273    pub fn fig_value_bool(value: *mut FigValue, b: bool, out_id: *mut FigNodeId) -> FigStatus;
274    pub fn fig_value_int(value: *mut FigValue, n: i64, out_id: *mut FigNodeId) -> FigStatus;
275    pub fn fig_value_uint(value: *mut FigValue, n: u64, out_id: *mut FigNodeId) -> FigStatus;
276    pub fn fig_value_number(
277        value: *mut FigValue,
278        raw: *const u8,
279        raw_len: usize,
280        is_float: bool,
281        out_id: *mut FigNodeId,
282    ) -> FigStatus;
283    pub fn fig_value_string(
284        value: *mut FigValue,
285        ptr: *const u8,
286        len: usize,
287        out_id: *mut FigNodeId,
288    ) -> FigStatus;
289    pub fn fig_value_extended(
290        value: *mut FigValue,
291        kind: c_int,
292        text: *const u8,
293        text_len: usize,
294        out_id: *mut FigNodeId,
295    ) -> FigStatus;
296    pub fn fig_value_seq(
297        value: *mut FigValue,
298        items: *const FigNodeId,
299        items_len: usize,
300        out_id: *mut FigNodeId,
301    ) -> FigStatus;
302    pub fn fig_value_map(
303        value: *mut FigValue,
304        entries: *const FigKeyValue,
305        entries_len: usize,
306        out_id: *mut FigNodeId,
307    ) -> FigStatus;
308    // ABI-mirror decl; the binding always serializes through the `_opts` form.
309    #[allow(dead_code)]
310    pub fn fig_value_serialize(
311        value: *mut FigValue,
312        root: FigNodeId,
313        format: c_int,
314        out_ptr: *mut *const u8,
315        out_len: *mut usize,
316    ) -> FigStatus;
317    pub fn fig_value_serialize_opts(
318        value: *mut FigValue,
319        root: FigNodeId,
320        format: c_int,
321        options: *const FigSerializeOptions,
322        out_ptr: *mut *const u8,
323        out_len: *mut usize,
324    ) -> FigStatus;
325}
326
327// ---- serialization diagnostics ----
328
329unsafe extern "C" {
330    pub fn fig_document_diagnose(
331        doc: *mut FigDocument,
332        format: c_int,
333        options: *const FigSerializeOptions,
334        out_count: *mut usize,
335    ) -> FigStatus;
336    pub fn fig_document_warning(
337        doc: *mut FigDocument,
338        index: usize,
339        out: *mut FigWarning,
340    ) -> FigStatus;
341    pub fn fig_value_diagnose(
342        value: *mut FigValue,
343        root: FigNodeId,
344        format: c_int,
345        options: *const FigSerializeOptions,
346        out_count: *mut usize,
347    ) -> FigStatus;
348    pub fn fig_value_warning(
349        value: *mut FigValue,
350        index: usize,
351        out: *mut FigWarning,
352    ) -> FigStatus;
353}
354
355// ---- editing (write path) ----
356
357pub enum FigEditor {}
358pub enum FigEmbed {}
359
360/// One step of a path: `kind == 0` selects mapping key `key_ptr[0..key_len]`;
361/// `kind == 1` selects sequence element `index`. Mirrors `FigPathSegment` in
362/// `fig.h`.
363#[repr(C)]
364#[derive(Clone, Copy, Debug)]
365pub struct FigPathSegment {
366    pub kind: i32,
367    pub key_ptr: *const u8,
368    pub key_len: usize,
369    pub index: usize,
370}
371
372/// A borrowed UTF-8 string slice (`ptr[0..len]`) passed across the C ABI.
373/// Mirrors `FigStr` in `fig.h`; used for the key list of `*_reorder_keys`.
374#[repr(C)]
375#[derive(Clone, Copy, Debug)]
376pub struct FigStr {
377    pub ptr: *const u8,
378    pub len: usize,
379}
380
381// `FigSpan`/`FigRegion`/`fig_embed_extract` mirror the low-level embed C ABI.
382// The Rust-facing consumer is `Embed` (which uses `fig_embed_*`); these are
383// declared for parity with the header and for any future low-level wrapper.
384#[repr(C)]
385#[derive(Clone, Copy, Debug, Default)]
386#[allow(dead_code)]
387pub struct FigSpan {
388    pub start: usize,
389    pub end: usize,
390}
391
392#[repr(C)]
393#[derive(Clone, Copy, Debug, Default)]
394#[allow(dead_code)]
395pub struct FigRegion {
396    /// Size-version tag: set to `size_of::<FigRegion>()` before
397    /// `fig_embed_extract` so the library only writes the fields this layout
398    /// covers. A zero `size` (e.g. from `Default`) makes the library write
399    /// nothing — always set it explicitly.
400    pub size: u32,
401    pub open_fence: FigSpan,
402    pub content: FigSpan,
403    pub close_fence: FigSpan,
404    pub body: FigSpan,
405}
406
407#[repr(C)]
408#[derive(Clone, Copy, Debug, Eq, PartialEq)]
409#[allow(dead_code)]
410pub enum FigEmbedType {
411    FrontmatterYaml = 0,
412    FrontmatterJson = 1,
413    EndmatterYaml = 2,
414    FrontmatterFig = 3,
415    PlusToml = 4,
416    FencedYaml = 5,
417    FencedJson = 6,
418    FencedToml = 7,
419    MdFrontmatterJson = 8,
420    MdFrontmatterToml = 9,
421    MdFrontmatterFig = 10,
422    HtmlScriptFig = 11,
423    HtmlScriptYaml = 12,
424    HtmlScriptJson = 13,
425    HtmlScriptToml = 14,
426    HtmlCodeFig = 15,
427    HtmlCodeYaml = 16,
428    HtmlCodeJson = 17,
429    HtmlCodeToml = 18,
430}
431
432unsafe extern "C" {
433    pub fn fig_editor_create(
434        input: *const u8,
435        input_len: usize,
436        format: c_int,
437        out_editor: *mut *mut FigEditor,
438    ) -> FigStatus;
439    pub fn fig_editor_destroy(editor: *mut FigEditor);
440
441    pub fn fig_editor_replace_val(
442        editor: *mut FigEditor,
443        path: *const FigPathSegment,
444        path_len: usize,
445        repl: *const u8,
446        repl_len: usize,
447    ) -> FigStatus;
448    pub fn fig_editor_replace_key(
449        editor: *mut FigEditor,
450        path: *const FigPathSegment,
451        path_len: usize,
452        repl: *const u8,
453        repl_len: usize,
454    ) -> FigStatus;
455    pub fn fig_editor_set(
456        editor: *mut FigEditor,
457        path: *const FigPathSegment,
458        path_len: usize,
459        val: *const u8,
460        val_len: usize,
461    ) -> FigStatus;
462    pub fn fig_editor_add_leading_comment(
463        editor: *mut FigEditor,
464        path: *const FigPathSegment,
465        path_len: usize,
466        text: *const u8,
467        text_len: usize,
468    ) -> FigStatus;
469    pub fn fig_editor_set_trailing_comment(
470        editor: *mut FigEditor,
471        path: *const FigPathSegment,
472        path_len: usize,
473        text: *const u8,
474        text_len: usize,
475    ) -> FigStatus;
476    pub fn fig_editor_delete_leading_comments(
477        editor: *mut FigEditor,
478        path: *const FigPathSegment,
479        path_len: usize,
480    ) -> FigStatus;
481    pub fn fig_editor_delete_trailing_comment(
482        editor: *mut FigEditor,
483        path: *const FigPathSegment,
484        path_len: usize,
485    ) -> FigStatus;
486    pub fn fig_editor_get_leading_comment(
487        editor: *mut FigEditor,
488        path: *const FigPathSegment,
489        path_len: usize,
490        out_ptr: *mut *const u8,
491        out_len: *mut usize,
492    ) -> FigStatus;
493    pub fn fig_editor_get_trailing_comment(
494        editor: *mut FigEditor,
495        path: *const FigPathSegment,
496        path_len: usize,
497        out_ptr: *mut *const u8,
498        out_len: *mut usize,
499    ) -> FigStatus;
500    pub fn fig_editor_insert_key(
501        editor: *mut FigEditor,
502        path: *const FigPathSegment,
503        path_len: usize,
504        key: *const u8,
505        key_len: usize,
506        val: *const u8,
507        val_len: usize,
508    ) -> FigStatus;
509    pub fn fig_editor_delete_key(
510        editor: *mut FigEditor,
511        path: *const FigPathSegment,
512        path_len: usize,
513    ) -> FigStatus;
514    pub fn fig_editor_append_seq(
515        editor: *mut FigEditor,
516        path: *const FigPathSegment,
517        path_len: usize,
518        val: *const u8,
519        val_len: usize,
520    ) -> FigStatus;
521    pub fn fig_editor_prepend_seq(
522        editor: *mut FigEditor,
523        path: *const FigPathSegment,
524        path_len: usize,
525        val: *const u8,
526        val_len: usize,
527    ) -> FigStatus;
528    pub fn fig_editor_remove_seq_item(
529        editor: *mut FigEditor,
530        path: *const FigPathSegment,
531        path_len: usize,
532        index: usize,
533    ) -> FigStatus;
534    pub fn fig_editor_move_key(
535        editor: *mut FigEditor,
536        src_path: *const FigPathSegment,
537        src_path_len: usize,
538        dest_path: *const FigPathSegment,
539        dest_path_len: usize,
540    ) -> FigStatus;
541    pub fn fig_editor_reorder_keys(
542        editor: *mut FigEditor,
543        path: *const FigPathSegment,
544        path_len: usize,
545        keys: *const FigStr,
546        keys_len: usize,
547    ) -> FigStatus;
548    pub fn fig_editor_move_item(
549        editor: *mut FigEditor,
550        path: *const FigPathSegment,
551        path_len: usize,
552        from: usize,
553        to: usize,
554    ) -> FigStatus;
555    pub fn fig_editor_reorder_items(
556        editor: *mut FigEditor,
557        path: *const FigPathSegment,
558        path_len: usize,
559        indices: *const usize,
560        indices_len: usize,
561    ) -> FigStatus;
562    pub fn fig_editor_set_sequence(
563        editor: *mut FigEditor,
564        path: *const FigPathSegment,
565        path_len: usize,
566        items: *const FigStr,
567        items_len: usize,
568    ) -> FigStatus;
569    pub fn fig_editor_source(
570        editor: *const FigEditor,
571        out_ptr: *mut *const u8,
572        out_len: *mut usize,
573    ) -> FigStatus;
574
575    pub fn fig_embed_extract(
576        input: *const u8,
577        input_len: usize,
578        embed_type: c_int,
579        out_region: *mut FigRegion,
580    ) -> FigStatus;
581
582    pub fn fig_embed_detect(
583        input: *const u8,
584        input_len: usize,
585        out_embed_type: *mut c_int,
586    ) -> FigStatus;
587
588    pub fn fig_embed_open(
589        input: *const u8,
590        input_len: usize,
591        embed_type: c_int,
592        out_embed: *mut *mut FigEmbed,
593    ) -> FigStatus;
594    pub fn fig_embed_open_or_init(
595        input: *const u8,
596        input_len: usize,
597        embed_type: c_int,
598        out_embed: *mut *mut FigEmbed,
599    ) -> FigStatus;
600    pub fn fig_embed_destroy(fm: *mut FigEmbed);
601
602    pub fn fig_embed_replace_val(
603        fm: *mut FigEmbed,
604        path: *const FigPathSegment,
605        path_len: usize,
606        repl: *const u8,
607        repl_len: usize,
608    ) -> FigStatus;
609    pub fn fig_embed_replace_key(
610        fm: *mut FigEmbed,
611        path: *const FigPathSegment,
612        path_len: usize,
613        repl: *const u8,
614        repl_len: usize,
615    ) -> FigStatus;
616    pub fn fig_embed_set(
617        fm: *mut FigEmbed,
618        path: *const FigPathSegment,
619        path_len: usize,
620        val: *const u8,
621        val_len: usize,
622    ) -> FigStatus;
623    pub fn fig_embed_add_leading_comment(
624        fm: *mut FigEmbed,
625        path: *const FigPathSegment,
626        path_len: usize,
627        text: *const u8,
628        text_len: usize,
629    ) -> FigStatus;
630    pub fn fig_embed_set_trailing_comment(
631        fm: *mut FigEmbed,
632        path: *const FigPathSegment,
633        path_len: usize,
634        text: *const u8,
635        text_len: usize,
636    ) -> FigStatus;
637    pub fn fig_embed_delete_leading_comments(
638        fm: *mut FigEmbed,
639        path: *const FigPathSegment,
640        path_len: usize,
641    ) -> FigStatus;
642    pub fn fig_embed_delete_trailing_comment(
643        fm: *mut FigEmbed,
644        path: *const FigPathSegment,
645        path_len: usize,
646    ) -> FigStatus;
647    pub fn fig_embed_get_leading_comment(
648        fm: *mut FigEmbed,
649        path: *const FigPathSegment,
650        path_len: usize,
651        out_ptr: *mut *const u8,
652        out_len: *mut usize,
653    ) -> FigStatus;
654    pub fn fig_embed_get_trailing_comment(
655        fm: *mut FigEmbed,
656        path: *const FigPathSegment,
657        path_len: usize,
658        out_ptr: *mut *const u8,
659        out_len: *mut usize,
660    ) -> FigStatus;
661    pub fn fig_embed_insert_key(
662        fm: *mut FigEmbed,
663        path: *const FigPathSegment,
664        path_len: usize,
665        key: *const u8,
666        key_len: usize,
667        val: *const u8,
668        val_len: usize,
669    ) -> FigStatus;
670    pub fn fig_embed_delete_key(
671        fm: *mut FigEmbed,
672        path: *const FigPathSegment,
673        path_len: usize,
674    ) -> FigStatus;
675    pub fn fig_embed_append_seq(
676        fm: *mut FigEmbed,
677        path: *const FigPathSegment,
678        path_len: usize,
679        val: *const u8,
680        val_len: usize,
681    ) -> FigStatus;
682    pub fn fig_embed_prepend_seq(
683        fm: *mut FigEmbed,
684        path: *const FigPathSegment,
685        path_len: usize,
686        val: *const u8,
687        val_len: usize,
688    ) -> FigStatus;
689    pub fn fig_embed_remove_seq_item(
690        fm: *mut FigEmbed,
691        path: *const FigPathSegment,
692        path_len: usize,
693        index: usize,
694    ) -> FigStatus;
695    pub fn fig_embed_move_key(
696        fm: *mut FigEmbed,
697        src_path: *const FigPathSegment,
698        src_path_len: usize,
699        dest_path: *const FigPathSegment,
700        dest_path_len: usize,
701    ) -> FigStatus;
702    pub fn fig_embed_reorder_keys(
703        fm: *mut FigEmbed,
704        path: *const FigPathSegment,
705        path_len: usize,
706        keys: *const FigStr,
707        keys_len: usize,
708    ) -> FigStatus;
709    pub fn fig_embed_move_item(
710        fm: *mut FigEmbed,
711        path: *const FigPathSegment,
712        path_len: usize,
713        from: usize,
714        to: usize,
715    ) -> FigStatus;
716    pub fn fig_embed_reorder_items(
717        fm: *mut FigEmbed,
718        path: *const FigPathSegment,
719        path_len: usize,
720        indices: *const usize,
721        indices_len: usize,
722    ) -> FigStatus;
723    pub fn fig_embed_set_sequence(
724        fm: *mut FigEmbed,
725        path: *const FigPathSegment,
726        path_len: usize,
727        items: *const FigStr,
728        items_len: usize,
729    ) -> FigStatus;
730    pub fn fig_embed_replace_body(
731        fm: *mut FigEmbed,
732        body: *const u8,
733        body_len: usize,
734    ) -> FigStatus;
735    pub fn fig_embed_render(
736        fm: *mut FigEmbed,
737        out_ptr: *mut *const u8,
738        out_len: *mut usize,
739    ) -> FigStatus;
740}