Skip to main content

spice/core/
neat.rs

1/*!
2Improvement on the procedurally generated functions.
3
4## Description
5
6The idiomatic Rust bindings to CSPICE can be very hard to generate in a procedural macro in some
7specific cases. You can find, in this module, functions wrapped from [`raw`] to better match
8an idiomatic usage. The improvements consists in functions:
9
10+ taking a string as input in C requires to also send the size of the pointer to a char array. In
11  Rust, you only send the string.
12+ taking an input for the array size and outputting a size, whereas a vector can be used
13+ reporting their result by appending to a caller allocated [cell][crate::core::cell::Cell], whereas
14  an owned cell can be returned
15
16This is the module the `lock` feature exposes whenever a function has a neat version; the raw
17version is exposed for the rest.
18*/
19
20use crate::core::cell::{Cell, CELL_MAXID};
21use crate::core::ffi::{UdFunb, UdFuns};
22use crate::raw;
23use crate::MAX_LEN_OUT;
24
25#[cfg(any(feature = "lock", doc))]
26use {crate::SpiceLock, spice_derive::impl_for};
27
28/// Default capacity, in double precision numbers, of the coverage windows allocated here.
29pub const CELL_MAXWIN: usize = 10_000;
30
31/* -------------------------------------------------------------------------------------------- */
32/* Strings sized with [`MAX_LEN_OUT`]                                                             */
33/* -------------------------------------------------------------------------------------------- */
34
35/**
36Translate the SPICE integer code of a body into a common name for that body.
37
38See [`raw::bodc2n`] for the raw interface.
39*/
40#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
41pub fn bodc2n(code: i32) -> (String, bool) {
42    raw::bodc2n(code, MAX_LEN_OUT as i32)
43}
44
45/**
46Translate a body ID code to either the corresponding name or, if no name exists, the string
47representation of the code.
48
49See [`raw::bodc2s`] for the raw interface.
50*/
51#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
52pub fn bodc2s(code: i32) -> String {
53    raw::bodc2s(code, MAX_LEN_OUT as i32)
54}
55
56/**
57Look up the name of a reference frame associated with an ID code.
58
59See [`raw::frmnam`] for the raw interface.
60*/
61#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
62pub fn frmnam(frcode: i32) -> String {
63    raw::frmnam(frcode, MAX_LEN_OUT as i32)
64}
65
66/**
67Convert an input epoch, in ephemeris seconds past J2000, to a UTC string.
68
69See [`raw::et2utc`] for the raw interface.
70*/
71#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
72pub fn et2utc(et: f64, format: &str, prec: i32) -> String {
73    raw::et2utc(et, format, prec, MAX_LEN_OUT as i32)
74}
75
76/**
77This routine converts an input epoch represented in TDB seconds past the TDB epoch of J2000 to a
78character string formatted to the specifications of a user's format picture.
79
80See [`raw::timout`] for the raw interface.
81*/
82#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
83pub fn timout(et: f64, pictur: &str) -> String {
84    raw::timout(et, pictur, MAX_LEN_OUT as i32)
85}
86
87/**
88Parse a time string, returning the seconds past J2000 and the error message, empty on success.
89
90See [`raw::tparse`] for the raw interface.
91*/
92#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
93pub fn tparse(string: &str) -> (f64, String) {
94    raw::tparse(string, MAX_LEN_OUT as i32)
95}
96
97/**
98Convert ephemeris seconds past J2000 to a spacecraft clock string.
99
100See [`raw::sce2s`] for the raw interface.
101*/
102#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
103pub fn sce2s(sc: i32, et: f64) -> String {
104    raw::sce2s(sc, et, MAX_LEN_OUT as i32)
105}
106
107/**
108Convert a double precision encoding of spacecraft clock time into a character representation.
109
110See [`raw::scdecd`] for the raw interface.
111*/
112#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
113pub fn scdecd(sc: i32, sclkdp: f64) -> String {
114    raw::scdecd(sc, sclkdp, MAX_LEN_OUT as i32)
115}
116
117/**
118Translate a surface ID code, together with a body ID code, to the corresponding surface name.
119
120See [`raw::srfc2s`] for the raw interface.
121*/
122#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
123pub fn srfc2s(code: i32, bodyid: i32) -> (String, bool) {
124    raw::srfc2s(code, bodyid, MAX_LEN_OUT as i32)
125}
126
127/**
128Translate a surface ID code, together with a body string, to the corresponding surface name.
129
130See [`raw::srfcss`] for the raw interface.
131*/
132#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
133pub fn srfcss(code: i32, bodstr: &str) -> (String, bool) {
134    raw::srfcss(code, bodstr, MAX_LEN_OUT as i32)
135}
136
137/**
138Return the file name, type, source and handle of a loaded kernel.
139
140See [`raw::kdata`] for the raw interface.
141*/
142#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
143pub fn kdata(which: i32, kind: &str) -> (String, String, String, i32, bool) {
144    raw::kdata(
145        which,
146        kind,
147        MAX_LEN_OUT as i32,
148        MAX_LEN_OUT as i32,
149        MAX_LEN_OUT as i32,
150    )
151}
152
153/**
154Return the type, source and handle of a loaded kernel, given its name.
155
156See [`raw::kinfo`] for the raw interface.
157*/
158#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
159pub fn kinfo(file: &str) -> (String, String, i32, bool) {
160    raw::kinfo(file, MAX_LEN_OUT as i32, MAX_LEN_OUT as i32)
161}
162
163/**
164Return the character values of a kernel pool variable.
165
166See [`raw::gcpool`] for the raw interface.
167*/
168#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
169pub fn gcpool(name: &str, start: usize, room: usize) -> Vec<String> {
170    raw::gcpool(name, start, room, MAX_LEN_OUT)
171}
172
173/**
174Fetch the `nth` string of a kernel pool variable, re-joining continuation lines.
175
176See [`raw::stpool`] for the raw interface.
177*/
178#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
179pub fn stpool(item: &str, nth: i32, contin: &str) -> (String, i32, bool) {
180    raw::stpool(item, nth, contin, MAX_LEN_OUT)
181}
182
183/**
184Determine the architecture and type of a SPICE kernel file.
185
186See [`raw::getfat`] for the raw interface.
187*/
188#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
189pub fn getfat(file: &str) -> (String, String) {
190    raw::getfat(file, MAX_LEN_OUT, MAX_LEN_OUT)
191}
192
193/**
194Return the field of view of an instrument given its name.
195
196See [`raw::getfvn`] for the raw interface.
197*/
198#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
199pub fn getfvn(inst: &str, room: usize) -> (String, String, [f64; 3], Vec<[f64; 3]>) {
200    raw::getfvn(inst, room, MAX_LEN_OUT, MAX_LEN_OUT)
201}
202
203/**
204The local solar time at a longitude on a body.
205
206See [`raw::et2lst`] for the raw interface.
207*/
208#[allow(clippy::type_complexity)]
209#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
210pub fn et2lst(et: f64, body: i32, lon: f64, kind: &str) -> (i32, i32, i32, String, String) {
211    raw::et2lst(et, body, lon, kind, MAX_LEN_OUT, MAX_LEN_OUT)
212}
213
214/**
215Build a time format picture from a sample time string.
216
217See [`raw::tpictr`] for the raw interface.
218*/
219#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
220pub fn tpictr(sample: &str) -> (String, bool, String) {
221    raw::tpictr(sample, MAX_LEN_OUT, MAX_LEN_OUT)
222}
223
224/**
225Set or retrieve a default used by the time routines.
226
227See [`raw::timdef`] for the raw interface.
228*/
229#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
230pub fn timdef(action: &str, item: &str, value: &str) -> String {
231    raw::timdef(action, item, value, MAX_LEN_OUT)
232}
233
234/**
235The name of the routine at a given depth in the traceback.
236
237See [`raw::trcnam`] for the raw interface.
238*/
239#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
240pub fn trcnam(index: i32) -> String {
241    raw::trcnam(index, MAX_LEN_OUT as i32)
242}
243
244/**
245Replace a marker in a string with the cardinal text of an integer.
246
247See [`raw::repmct`] for the raw interface.
248*/
249#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
250pub fn repmct(input: &str, marker: &str, value: i32, strcase: char) -> String {
251    raw::repmct(input, marker, value, strcase, MAX_LEN_OUT as i32)
252}
253
254/**
255Search for the segment of an SPK that covers a body at an epoch.
256
257See [`raw::spksfs`] for the raw interface.
258*/
259#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
260pub fn spksfs(body: i32, et: f64) -> (i32, [f64; raw::SPK_DSCSIZ], String, bool) {
261    raw::spksfs(body, et, MAX_LEN_OUT)
262}
263
264/**
265Read the whole comment area of a DAF.
266
267See [`raw::dafec`] for the raw interface.
268*/
269#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
270pub fn dafec(handle: i32) -> Vec<String> {
271    let mut lines = Vec::new();
272    loop {
273        let (batch, done) = raw::dafec(handle, 64, MAX_LEN_OUT);
274        lines.extend(batch);
275        if done {
276            return lines;
277        }
278    }
279}
280
281/**
282Read the whole comment area of a DAS.
283
284See [`raw::dasec`] for the raw interface.
285*/
286#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
287pub fn dasec(handle: i32) -> Vec<String> {
288    let mut lines = Vec::new();
289    loop {
290        let (batch, done) = raw::dasec(handle, 64, MAX_LEN_OUT);
291        lines.extend(batch);
292        if done {
293            return lines;
294        }
295    }
296}
297
298/**
299Return the names of the kernel pool variables matching a template.
300
301See [`raw::gnpool`] for the raw interface.
302*/
303#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
304pub fn gnpool(name: &str, start: usize, room: usize) -> Vec<String> {
305    raw::gnpool(name, start, room, MAX_LEN_OUT)
306}
307
308/**
309Return the field-of-view parameters of an instrument, given its NAIF ID code.
310
311See [`raw::getfov`] for the raw interface.
312*/
313#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
314pub fn getfov(instid: i32, room: usize) -> (String, String, [f64; 3], Vec<[f64; 3]>) {
315    raw::getfov(instid, room, MAX_LEN_OUT, MAX_LEN_OUT)
316}
317
318/* -------------------------------------------------------------------------------------------- */
319/* Arrays sized from the file itself                                                              */
320/* -------------------------------------------------------------------------------------------- */
321
322/**
323Fetch every triangular plate of a type 2 DSK segment.
324
325See [`raw::dskp02`] for the raw interface.
326*/
327#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
328pub fn dskp02(handle: i32, dladsc: raw::DLADSC) -> Vec<[i32; 3]> {
329    let (_nv, np) = raw::dskz02(handle, dladsc);
330    raw::dskp02(handle, dladsc, 1, np.max(0) as usize)
331}
332
333/**
334Fetch every vertex of a type 2 DSK segment.
335
336See [`raw::dskv02`] for the raw interface.
337*/
338#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
339pub fn dskv02(handle: i32, dladsc: raw::DLADSC) -> Vec<[f64; 3]> {
340    let (nv, _np) = raw::dskz02(handle, dladsc);
341    raw::dskv02(handle, dladsc, 1, nv.max(0) as usize)
342}
343
344/* -------------------------------------------------------------------------------------------- */
345/* Cells allocated on the caller's behalf                                                         */
346/* -------------------------------------------------------------------------------------------- */
347
348/**
349Split a list on a single delimiter, sizing the result for you.
350
351See [`raw::lparse`] for the raw interface.
352*/
353#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
354pub fn lparse(list: &str, delim: &str) -> Vec<String> {
355    raw::lparse(list, delim, list.len() + 1, list.len() + 1)
356}
357
358/**
359Split a list on any of a set of delimiters, sizing the result for you.
360
361See [`raw::lparsm`] for the raw interface.
362*/
363#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
364pub fn lparsm(list: &str, delims: &str) -> Vec<String> {
365    raw::lparsm(list, delims, list.len() + 1, list.len() + 1)
366}
367
368/**
369Convert a string to lower case.
370
371See [`raw::lcase`] for the raw interface.
372*/
373#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
374pub fn lcase(input: &str) -> String {
375    raw::lcase(input, input.len() as i32 + 1)
376}
377
378/**
379Convert a string to upper case.
380
381See [`raw::ucase`] for the raw interface.
382*/
383#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
384pub fn ucase(input: &str) -> String {
385    raw::ucase(input, input.len() as i32 + 1)
386}
387
388/**
389Compress runs of a delimiter down to `n` of them.
390
391See [`raw::cmprss`] for the raw interface.
392*/
393#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
394pub fn cmprss(delim: char, n: i32, input: &str) -> String {
395    raw::cmprss(delim, n, input, input.len() as i32 + 1)
396}
397
398/**
399Split a string at the first run of blanks, into the first word and the rest.
400
401See [`raw::nextwd`] for the raw interface.
402*/
403#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
404pub fn nextwd(string: &str) -> (String, String) {
405    raw::nextwd(string, string.len() + 1, string.len() + 1)
406}
407
408/**
409Replace a marker in a string with a string.
410
411See [`raw::repmc`] for the raw interface.
412*/
413#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
414pub fn repmc(input: &str, marker: &str, value: &str) -> String {
415    raw::repmc(input, marker, value, (input.len() + value.len() + 1) as i32)
416}
417
418/**
419Replace a marker in a string with a double precision number.
420
421See [`raw::repmd`] for the raw interface.
422*/
423#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
424pub fn repmd(input: &str, marker: &str, value: f64, sigdig: i32) -> String {
425    raw::repmd(input, marker, value, sigdig, MAX_LEN_OUT as i32)
426}
427
428/**
429Replace a marker in a string with an integer.
430
431See [`raw::repmi`] for the raw interface.
432*/
433#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
434pub fn repmi(input: &str, marker: &str, value: i32) -> String {
435    raw::repmi(input, marker, value, MAX_LEN_OUT as i32)
436}
437
438/**
439Find the set of body ID codes of all objects for which topographic data are provided in a specified
440DSK file.
441
442See [`raw::dskobj`] for the raw interface.
443*/
444#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
445pub fn dskobj(dsk: &str) -> Cell<i32> {
446    let mut bodids = Cell::new(CELL_MAXID);
447    raw::dskobj(dsk, &mut bodids);
448    bodids
449}
450
451/**
452Find the set of surface ID codes for all surfaces associated with a given body in a specified DSK
453file.
454
455See [`raw::dsksrf`] for the raw interface.
456*/
457#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
458pub fn dsksrf(dsk: &str, bodyid: i32) -> Cell<i32> {
459    let mut srfids = Cell::new(CELL_MAXID);
460    raw::dsksrf(dsk, bodyid, &mut srfids);
461    srfids
462}
463
464/**
465Find the set of ID codes of all objects in a specified SPK file.
466
467See [`raw::spkobj`] for the raw interface.
468*/
469#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
470pub fn spkobj(spk: &str) -> Cell<i32> {
471    let mut ids = Cell::new(CELL_MAXID);
472    raw::spkobj(spk, &mut ids);
473    ids
474}
475
476/**
477Find the coverage window for a specified ephemeris object in a specified SPK file.
478
479See [`raw::spkcov`] for the raw interface.
480*/
481#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
482pub fn spkcov(spk: &str, idcode: i32) -> Cell<f64> {
483    let mut cover = Cell::new(CELL_MAXWIN);
484    raw::spkcov(spk, idcode, &mut cover);
485    cover
486}
487
488/**
489Find the set of ID codes of all objects in a specified CK file.
490
491See [`raw::ckobj`] for the raw interface.
492*/
493#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
494pub fn ckobj(ck: &str) -> Cell<i32> {
495    let mut ids = Cell::new(CELL_MAXID);
496    raw::ckobj(ck, &mut ids);
497    ids
498}
499
500/**
501Find the coverage window for a specified object in a specified CK file.
502
503See [`raw::ckcov`] for the raw interface.
504*/
505#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
506pub fn ckcov(
507    ck: &str,
508    idcode: i32,
509    needav: bool,
510    level: &str,
511    tol: f64,
512    timsys: &str,
513) -> Cell<f64> {
514    let mut cover = Cell::new(CELL_MAXWIN);
515    raw::ckcov(ck, idcode, needav, level, tol, timsys, &mut cover);
516    cover
517}
518
519/**
520Find the coverage window for a specified reference frame in a specified binary PCK file.
521
522See [`raw::pckcov`] for the raw interface.
523*/
524#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
525pub fn pckcov(pck: &str, idcode: i32) -> Cell<f64> {
526    let mut cover = Cell::new(CELL_MAXWIN);
527    raw::pckcov(pck, idcode, &mut cover);
528    cover
529}
530
531/**
532Determine the time windows, within a confinement window, when one body is occulted by or in transit
533across another, as seen from an observer.
534
535See [`raw::gfoclt`] for the raw interface.
536*/
537#[allow(clippy::too_many_arguments)]
538#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
539pub fn gfoclt(
540    occtyp: &str,
541    front: &str,
542    fshape: &str,
543    fframe: &str,
544    back: &str,
545    bshape: &str,
546    bframe: &str,
547    abcorr: &str,
548    obsrvr: &str,
549    step: f64,
550    cnfine: &mut Cell<f64>,
551) -> Cell<f64> {
552    let mut result = Cell::new(CELL_MAXWIN);
553    raw::gfoclt(
554        occtyp,
555        front,
556        fshape,
557        fframe,
558        back,
559        bshape,
560        bframe,
561        abcorr,
562        obsrvr,
563        step,
564        cnfine,
565        &mut result,
566    );
567    result
568}
569
570/// Generate the neat forms of the searches that compare a quantity against a reference value.
571macro_rules! gf_search {
572    ($($name:ident($($arg:ident: $ty:ty),*), $doc:expr);* $(;)?) => {$(
573        #[doc = $doc]
574        ///
575        #[doc = concat!("See [`raw::", stringify!($name), "`] for the raw interface.")]
576        #[allow(clippy::too_many_arguments)]
577        #[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
578        pub fn $name(
579            $($arg: $ty,)*
580            relate: &str,
581            refval: f64,
582            adjust: f64,
583            step: f64,
584            cnfine: &mut Cell<f64>,
585        ) -> Cell<f64> {
586            let mut result = Cell::new(CELL_MAXWIN);
587            raw::$name(
588                $($arg,)* relate, refval, adjust, step, (CELL_MAXWIN / 2) as i32, cnfine,
589                &mut result,
590            );
591            result
592        }
593    )*};
594}
595
596gf_search! {
597    gfdist(target: &str, abcorr: &str, obsrvr: &str),
598        "Search for times when the distance to a target meets a condition.";
599    gfrr(target: &str, abcorr: &str, obsrvr: &str),
600        "Search for times when the range rate of a target meets a condition.";
601    gfpa(target: &str, illmn: &str, abcorr: &str, obsrvr: &str),
602        "Search for times when the phase angle of a target meets a condition.";
603    gfposc(
604        target: &str, frame: &str, abcorr: &str, obsrvr: &str, crdsys: &str, coord: &str
605    ),
606        "Search for times when a coordinate of a target's position meets a condition.";
607    gfsubc(
608        target: &str, fixref: &str, method: &str, abcorr: &str, obsrvr: &str, crdsys: &str,
609        coord: &str
610    ),
611        "Search for times when a coordinate of the sub-observer point meets a condition.";
612    gfsntc(
613        target: &str, fixref: &str, method: &str, abcorr: &str, obsrvr: &str, dref: &str,
614        dvec: [f64; 3], crdsys: &str, coord: &str
615    ),
616        "Search for times when a coordinate of a ray-surface intercept meets a condition.";
617    gfsep(
618        targ1: &str, shape1: &str, frame1: &str, targ2: &str, shape2: &str, frame2: &str,
619        abcorr: &str, obsrvr: &str
620    ),
621        "Search for times when the angular separation of two targets meets a condition.";
622    gfilum(
623        method: &str, angtyp: &str, target: &str, illmn: &str, fixref: &str, abcorr: &str,
624        obsrvr: &str, spoint: [f64; 3]
625    ),
626        "Search for times when an illumination angle at a surface point meets a condition.";
627}
628
629/**
630Search for times when a ray is in the field of view of an instrument.
631
632See [`raw::gfrfov`] for the raw interface.
633*/
634#[allow(clippy::too_many_arguments)]
635#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
636pub fn gfrfov(
637    inst: &str,
638    raydir: [f64; 3],
639    rframe: &str,
640    abcorr: &str,
641    obsrvr: &str,
642    step: f64,
643    cnfine: &mut Cell<f64>,
644) -> Cell<f64> {
645    let mut result = Cell::new(CELL_MAXWIN);
646    raw::gfrfov(
647        inst,
648        raydir,
649        rframe,
650        abcorr,
651        obsrvr,
652        step,
653        cnfine,
654        &mut result,
655    );
656    result
657}
658
659/**
660Search for times when a target is in the field of view of an instrument.
661
662See [`raw::gftfov`] for the raw interface.
663*/
664#[allow(clippy::too_many_arguments)]
665#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
666pub fn gftfov(
667    inst: &str,
668    target: &str,
669    tshape: &str,
670    tframe: &str,
671    abcorr: &str,
672    obsrvr: &str,
673    step: f64,
674    cnfine: &mut Cell<f64>,
675) -> Cell<f64> {
676    let mut result = Cell::new(CELL_MAXWIN);
677    raw::gftfov(
678        inst,
679        target,
680        tshape,
681        tframe,
682        abcorr,
683        obsrvr,
684        step,
685        cnfine,
686        &mut result,
687    );
688    result
689}
690
691/**
692Search for times when a scalar function the caller supplies meets a condition.
693
694See [`raw::gfuds`] for the raw interface.
695*/
696#[allow(clippy::too_many_arguments)]
697#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
698pub fn gfuds(
699    udfuns: UdFuns,
700    udfunb: UdFunb,
701    relate: &str,
702    refval: f64,
703    adjust: f64,
704    step: f64,
705    cnfine: &mut Cell<f64>,
706) -> Cell<f64> {
707    let mut result = Cell::new(CELL_MAXWIN);
708    raw::gfuds(
709        udfuns,
710        udfunb,
711        relate,
712        refval,
713        adjust,
714        step,
715        (CELL_MAXWIN / 2) as i32,
716        cnfine,
717        &mut result,
718    );
719    result
720}
721
722/**
723Search for times when a boolean function the caller supplies is true.
724
725See [`raw::gfudb`] for the raw interface.
726*/
727#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
728pub fn gfudb(udfuns: UdFuns, udfunb: UdFunb, step: f64, cnfine: &mut Cell<f64>) -> Cell<f64> {
729    let mut result = Cell::new(CELL_MAXWIN);
730    raw::gfudb(udfuns, udfunb, step, cnfine, &mut result);
731    result
732}
733
734/**
735Find the set of reference frame class ID codes of all frames in a specified binary PCK file.
736
737See [`raw::pckfrm`] for the raw interface.
738*/
739#[cfg_attr(any(feature = "lock", doc), impl_for(SpiceLock))]
740pub fn pckfrm(pck: &str) -> Cell<i32> {
741    let mut ids = Cell::new(CELL_MAXID);
742    raw::pckfrm(pck, &mut ids);
743    ids
744}