tskit/
flags.rs

1use crate::bindings as ll_bindings;
2use crate::RawFlags;
3use bitflags::bitflags;
4
5macro_rules! flag_builder_api {
6    ($(#[$attr:meta])* => $name: ident, $flag: ident) => {
7        $(#[$attr])*
8        pub fn $name(self) -> Self {
9            self | Self::$flag
10        }
11    };
12}
13
14bitflags! {
15    /// Control the behavior of [`crate::TableCollection::simplify`]
16    /// and [`crate::TreeSequence::simplify`]
17    ///
18    /// Inclusion of values sets an option to `true`.
19    /// The default behavior (`NONE`) is to perform the algorithm
20    /// as described in Kelleher *et al.* (2018), 10.1371/journal.pcbi.1006581.
21    ///
22    /// The documentation for each field is taken from the `tskit` primary
23    /// docs.
24    ///
25    /// # Examples
26    ///
27    /// ## Building up flags
28    ///
29    /// ### Default flags
30    ///
31    /// ```
32    /// let flags = tskit::SimplificationOptions::default();
33    /// assert_eq!(flags, tskit::SimplificationOptions::NONE);
34    /// ```
35    ///
36    /// ### Using a "builder" API
37    ///
38    /// ```
39    /// let flags =
40    /// tskit::SimplificationOptions::default().keep_unary().filter_populations().filter_sites();
41    /// assert!(flags.contains(tskit::SimplificationOptions::KEEP_UNARY));
42    /// assert!(flags.contains(tskit::SimplificationOptions::FILTER_POPULATIONS));
43    /// assert!(flags.contains(tskit::SimplificationOptions::FILTER_SITES));
44    /// ```
45    #[derive(Default)]
46    #[repr(transparent)]
47    pub struct SimplificationOptions: RawFlags {
48        /// Default behavior
49        const NONE = 0;
50        const FILTER_SITES = ll_bindings::TSK_SIMPLIFY_FILTER_SITES;
51        /// If True, remove any populations that are not referenced by
52        /// nodes after simplification; new population IDs are allocated
53        /// sequentially from zero.
54        /// If False, the population table will not be altered in any way.
55        const FILTER_POPULATIONS = ll_bindings::TSK_SIMPLIFY_FILTER_POPULATIONS;
56        /// If True, remove any individuals that are not referenced by nodes
57        /// after simplification; new individual IDs are allocated sequentially
58        /// from zero. If False, the individual table will not be altered in any way.
59        const FILTER_INDIVIDUALS = ll_bindings::TSK_SIMPLIFY_FILTER_INDIVIDUALS;
60        /// Whether to reduce the topology down to the trees that are present at sites.
61        const REDUCE_TO_SITE_TOPOLOGY = ll_bindings::TSK_SIMPLIFY_REDUCE_TO_SITE_TOPOLOGY;
62        /// If True, preserve unary nodes (i.e. nodes with exactly one child)
63        /// that exist on the path from samples to root.
64        const KEEP_UNARY  = ll_bindings::TSK_SIMPLIFY_KEEP_UNARY;
65        /// Whether to retain history ancestral to the MRCA of the samples.
66        const KEEP_INPUT_ROOTS = ll_bindings::TSK_SIMPLIFY_KEEP_INPUT_ROOTS;
67        ///  If True, preserve unary nodes that exist on the path from samples
68        ///  to root, but only if they are associated with an individual
69        ///  in the individuals table.
70        ///  Cannot be specified at the same time as `KEEP_UNARY`.
71        const KEEP_UNARY_IN_INDIVIDUALS  = ll_bindings::TSK_SIMPLIFY_KEEP_UNARY_IN_INDIVIDUALS;
72    }
73}
74
75impl SimplificationOptions {
76    flag_builder_api!(
77    /// Update to set [`KEEP_INPUT_ROOTS`](crate::SimplificationOptions::KEEP_INPUT_ROOTS).
78    ///
79    /// # Examples
80    ///
81    /// ```
82    /// let f = tskit::SimplificationOptions::default().keep_input_roots();
83    /// assert!(f.contains(tskit::SimplificationOptions::KEEP_INPUT_ROOTS));
84    /// ```
85    => keep_input_roots, KEEP_INPUT_ROOTS);
86
87    flag_builder_api!(
88    /// Update to set [`KEEP_UNARY`](crate::SimplificationOptions::KEEP_UNARY).
89    ///
90    /// # Examples
91    ///
92    /// ```
93    /// let f = tskit::SimplificationOptions::default().keep_unary();
94    /// assert!(f.contains(tskit::SimplificationOptions::KEEP_UNARY));
95    /// ```
96    => keep_unary, KEEP_UNARY);
97
98    flag_builder_api!(
99    /// Update to set [`KEEP_UNARY_IN_INDIVIDUALS`](crate::SimplificationOptions::KEEP_UNARY_IN_INDIVIDUALS).
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// let f = tskit::SimplificationOptions::default().keep_unary_in_individuals();
105    /// assert!(f.contains(tskit::SimplificationOptions::KEEP_UNARY_IN_INDIVIDUALS));
106    /// ```
107    => keep_unary_in_individuals, KEEP_UNARY_IN_INDIVIDUALS);
108
109    flag_builder_api!(
110    /// Update to set [`FILTER_POPULATIONS`](crate::SimplificationOptions::FILTER_POPULATIONS).
111    ///
112    /// # Examples
113    ///
114    /// ```
115    /// let f = tskit::SimplificationOptions::default().filter_populations();
116    /// assert!(f.contains(tskit::SimplificationOptions::FILTER_POPULATIONS));
117    /// ```
118    => filter_populations, FILTER_POPULATIONS);
119
120    flag_builder_api!(
121    /// Update to set [`FILTER_SITES`](crate::SimplificationOptions::FILTER_SITES).
122    ///
123    /// # Examples
124    ///
125    /// ```
126    /// let f = tskit::SimplificationOptions::default().filter_sites();
127    /// assert!(f.contains(tskit::SimplificationOptions::FILTER_SITES));
128    /// ```
129    => filter_sites, FILTER_SITES);
130
131    flag_builder_api!(
132    /// Update to set [`REDUCE_TO_SITE_TOPOLOGY`](crate::SimplificationOptions::REDUCE_TO_SITE_TOPOLOGY).
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// let f = tskit::SimplificationOptions::default().reduce_to_site_topology();
138    /// assert!(f.contains(tskit::SimplificationOptions::REDUCE_TO_SITE_TOPOLOGY));
139    /// ```
140    => reduce_to_site_topology, REDUCE_TO_SITE_TOPOLOGY);
141
142    flag_builder_api!(
143    /// Update to set [`FILTER_INDIVIDUALS`](crate::SimplificationOptions::FILTER_INDIVIDUALS).
144    ///
145    /// # Examples
146    ///
147    /// ```
148    /// let f = tskit::SimplificationOptions::default().filter_individuals();
149    /// assert!(f.contains(tskit::SimplificationOptions::FILTER_INDIVIDUALS));
150    /// ```
151    => filter_individuals, FILTER_INDIVIDUALS);
152}
153
154bitflags! {
155    /// Modify behavior of [`crate::TableCollection::clear`].
156    ///
157    /// # Examples
158    ///
159    /// ## Set default (empty) flags
160    ///
161    /// ```
162    /// let f = tskit::TableClearOptions::default();
163    /// assert_eq!(f, tskit::TableClearOptions::NONE);
164    /// ```
165    ///
166    /// ## Builder API
167    ///
168    /// ```
169    /// let f = tskit::TableClearOptions::default().clear_metadata_schema();
170    /// assert_eq!(f, tskit::TableClearOptions::CLEAR_METADATA_SCHEMAS);
171    /// ```
172    ///
173    /// ```
174    /// let f = tskit::TableClearOptions::default().clear_ts_metadata_and_schema();
175    /// assert_eq!(f, tskit::TableClearOptions::CLEAR_TS_METADATA_SCHEMA);
176    /// ```
177    ///
178    /// ```
179    /// let f = tskit::TableClearOptions::default().clear_provenance();
180    /// assert_eq!(f, tskit::TableClearOptions::CLEAR_PROVENANCE);
181    ///
182    /// ```
183    /// let f = tskit::TableClearOptions::default().clear_metadata_schema().clear_ts_metadata_and_schema();
184    /// assert!(f.contains(tskit::TableClearOptions::CLEAR_METADATA_SCHEMAS));
185    /// assert!(f.contains(tskit::TableClearOptions::CLEAR_TS_METADATA_SCHEMA));
186    /// let f = f.clear();
187    /// assert!(f.contains(tskit::TableClearOptions::CLEAR_METADATA_SCHEMAS));
188    /// assert!(f.contains(tskit::TableClearOptions::CLEAR_TS_METADATA_SCHEMA));
189    /// assert!(f.contains(tskit::TableClearOptions::CLEAR_PROVENANCE);
190    /// ```
191    #[derive(Default)]
192    #[repr(transparent)]
193    pub struct TableClearOptions : RawFlags {
194        /// Default behavior.
195        const NONE = 0;
196        const CLEAR_METADATA_SCHEMAS = ll_bindings::TSK_CLEAR_METADATA_SCHEMAS;
197        const CLEAR_TS_METADATA_SCHEMA = ll_bindings::TSK_CLEAR_TS_METADATA_AND_SCHEMA;
198        const CLEAR_PROVENANCE = ll_bindings::TSK_CLEAR_PROVENANCE;
199    }
200}
201
202impl TableClearOptions {
203    flag_builder_api!(
204        /// Set [`CLEAR_METADATA_SCHEMAS`](crate::TableClearOptions::CLEAR_METADATA_SCHEMAS)
205        => clear_metadata_schema, CLEAR_METADATA_SCHEMAS);
206    flag_builder_api!(
207        /// Set [`CLEAR_TS_METADATA_SCHEMA`](crate::TableClearOptions::CLEAR_TS_METADATA_SCHEMA)
208        => clear_ts_metadata_and_schema, CLEAR_TS_METADATA_SCHEMA);
209    flag_builder_api!(
210        /// Set [`CLEAR_PROVENANCE`](crate::TableClearOptions::CLEAR_PROVENANCE)
211        => clear_provenance, CLEAR_PROVENANCE);
212}
213
214bitflags! {
215    /// Modify behavior of [`crate::TableCollection::equals`].
216    ///
217    /// # Examples
218    ///
219    /// ## Set default (empty) flags
220    ///
221    /// ```
222    /// let f = tskit::TableEqualityOptions::default();
223    /// assert_eq!(f, tskit::TableEqualityOptions::NONE);
224    /// ```
225    ///
226    /// ## Builder API
227    ///
228    /// ```
229    /// let f = tskit::TableEqualityOptions::default().ignore_metadata();
230    /// assert_eq!(f, tskit::TableEqualityOptions::IGNORE_METADATA);
231    /// ```
232    ///
233    /// ```
234    /// let f = tskit::TableEqualityOptions::default().ignore_ts_metadata();
235    /// assert_eq!(f, tskit::TableEqualityOptions::IGNORE_TS_METADATA);
236    /// ```
237    ///
238    /// ```
239    /// let f = tskit::TableEqualityOptions::default().ignore_timestamps();
240    /// assert_eq!(f, tskit::TableEqualityOptions::IGNORE_TIMESTAMPS);
241    /// ```
242    ///
243    /// ```
244    /// let f = tskit::TableEqualityOptions::default().ignore_provenance();
245    /// assert_eq!(f, tskit::TableEqualityOptions::IGNORE_PROVENANCE);
246    /// let f = f.ignore_metadata();
247    /// assert!(f.contains(tskit::TableEqualityOptions::IGNORE_PROVENANCE));
248    /// assert!(f.contains(tskit::TableEqualityOptions::IGNORE_METADATA));
249    /// ```
250    ///
251    /// ### Method chaining
252    ///
253    /// ```
254    /// let f = tskit::TableEqualityOptions::default().ignore_provenance().ignore_metadata();
255    /// assert!(f.contains(tskit::TableEqualityOptions::IGNORE_PROVENANCE));
256    /// assert!(f.contains(tskit::TableEqualityOptions::IGNORE_METADATA));
257    /// ```
258    #[derive(Default)]
259    #[repr(transparent)]
260    pub struct TableEqualityOptions : RawFlags {
261        /// Default behavior.
262        const NONE = 0;
263        const IGNORE_METADATA = ll_bindings::TSK_CMP_IGNORE_METADATA;
264        const IGNORE_TS_METADATA = ll_bindings::TSK_CMP_IGNORE_TS_METADATA;
265        const IGNORE_PROVENANCE = ll_bindings::TSK_CMP_IGNORE_PROVENANCE;
266        const IGNORE_TIMESTAMPS = ll_bindings::TSK_CMP_IGNORE_TIMESTAMPS;
267    }
268}
269
270impl TableEqualityOptions {
271    flag_builder_api!(
272        /// Set [`IGNORE_METADATA`](crate::TableEqualityOptions::IGNORE_METADATA)
273        => ignore_metadata, IGNORE_METADATA);
274    flag_builder_api!(
275        /// Set [`IGNORE_TS_METADATA`](crate::TableEqualityOptions::IGNORE_TS_METADATA)
276        => ignore_ts_metadata, IGNORE_TS_METADATA);
277    flag_builder_api!(
278        /// Set [:IGNORE_PROVENANCE`](crate::TableEqualityOptions::IGNORE_PROVENANCE)
279        => ignore_provenance, IGNORE_PROVENANCE);
280    flag_builder_api!(
281        /// Set [`IGNORE_TIMESTAMPS`](crate::TableEqualityOptions::IGNORE_TIMESTAMPS)
282        => ignore_timestamps, IGNORE_TIMESTAMPS);
283}
284
285bitflags! {
286    /// Modify behavior of [`crate::TableCollection::sort`].
287    ///
288    /// # Examples
289    ///
290    /// ## Default (empty) flags
291    ///
292    /// ```
293    /// let f = tskit::TableSortOptions::default();
294    /// assert_eq!(f, tskit::TableSortOptions::NONE);
295    /// ```
296    ///
297    /// ## Builder API
298    ///
299    /// These methods can all be chained.
300    ///
301    /// ```
302    /// let f = tskit::TableSortOptions::default().no_check_integrity();
303    /// assert_eq!(f, tskit::TableSortOptions::NO_CHECK_INTEGRITY);
304    /// ```
305    #[derive(Default)]
306    #[repr(transparent)]
307    pub struct TableSortOptions : RawFlags {
308        /// Default behavior.
309        const NONE = 0;
310        /// Do not validate contents of edge table.
311        const NO_CHECK_INTEGRITY = ll_bindings::TSK_NO_CHECK_INTEGRITY;
312    }
313}
314
315impl TableSortOptions {
316    flag_builder_api!(
317        /// Set [`NO_CHECK_INTEGRITY`](crate::TableSortOptions::NO_CHECK_INTEGRITY)
318        => no_check_integrity, NO_CHECK_INTEGRITY);
319}
320
321bitflags! {
322    /// Modify behavior of [`crate::TableCollection::sort_individuals`].
323    ///
324    /// # Examples
325    ///
326    /// ## Default (empty) flags
327    ///
328    /// ```
329    /// let f = tskit::IndividualTableSortOptions::default();
330    /// assert_eq!(f, tskit::IndividualTableSortOptions::NONE);
331    /// ```
332    #[derive(Default)]
333    #[repr(transparent)]
334    pub struct IndividualTableSortOptions : RawFlags {
335        /// Default behavior.
336        const NONE = 0;
337    }
338}
339
340bitflags! {
341    /// Specify the behavior of iterating over [`Tree`] objects.
342    /// See [`TreeSequence::tree_iterator`].
343    ///
344    /// # Examples
345    ///
346    /// ## Default (empty) flags
347    ///
348    /// ```
349    /// let f = tskit::TreeFlags::default();
350    /// assert_eq!(f, tskit::TreeFlags::NONE);
351    /// ```
352    ///
353    /// ## Builder API
354    ///
355    /// These methods can be chained.
356    ///
357    /// ```
358    /// let f = tskit::TreeFlags::default().sample_lists();
359    /// assert_eq!(f, tskit::TreeFlags::SAMPLE_LISTS);
360    /// ```
361    ///
362    /// ```
363    /// let f = tskit::TreeFlags::default().no_sample_counts();
364    /// assert_eq!(f, tskit::TreeFlags::NO_SAMPLE_COUNTS);
365    /// ```
366    #[derive(Default)]
367    #[repr(transparent)]
368    pub struct TreeFlags: RawFlags {
369        /// Default behavior.
370        const NONE = 0;
371        /// Update sample lists, enabling [`Tree::samples`].
372        const SAMPLE_LISTS = ll_bindings::TSK_SAMPLE_LISTS;
373        /// Do *not* update the number of samples descending
374        /// from each node. The default is to update these
375        /// counts.
376        const NO_SAMPLE_COUNTS = ll_bindings::TSK_NO_SAMPLE_COUNTS;
377    }
378}
379
380impl TreeFlags {
381    flag_builder_api!(
382        /// Set [`SAMPLE_LISTS`](crate::TreeFlags::SAMPLE_LISTS)
383        => sample_lists, SAMPLE_LISTS);
384    flag_builder_api!(
385        /// Set [`NO_SAMPLE_COUNTS`](crate::TreeFlags::NO_SAMPLE_COUNTS)
386        => no_sample_counts, NO_SAMPLE_COUNTS);
387}
388
389bitflags! {
390    /// Modify behavior of [`crate::TableCollection::dump`].
391    ///
392    /// # Examples
393    ///
394    /// ## Default (empty) flags
395    ///
396    /// ```
397    /// let f = tskit::TableOutputOptions::default();
398    /// assert_eq!(f, tskit::TableOutputOptions::NONE);
399    /// ```
400    ///
401    /// # Note
402    ///
403    /// We intentionally do *not* provide the TSK_NO_BUILD_INDEXES
404    /// flag.  Rather, we treat the various "dump" functions as
405    /// operations on immutable objects.  Thus, if indexes are desired
406    /// when outputting a [`crate::TableCollection`], then
407    /// call [`crate::TableCollection::build_index`] prior to calling
408    /// [`crate::TableCollection::dump`].
409    #[derive(Default)]
410    #[repr(transparent)]
411    pub struct TableOutputOptions : RawFlags {
412        const NONE = 0;
413    }
414}
415
416bitflags! {
417    /// Modify behavior of [`crate::TableCollection::tree_sequence`]
418    /// and [`crate::TreeSequence::new`].
419    ///
420    /// # Examples
421    ///
422    /// ## Default (empty) flags
423    ///
424    /// ```
425    /// let f = tskit::TreeSequenceFlags::default();
426    /// assert_eq!(f, tskit::TreeSequenceFlags::NONE);
427    /// ```
428    ///
429    /// ## Builder API
430    ///
431    /// These methods may be chained.
432    ///
433    /// ```
434    /// let f = tskit::TreeSequenceFlags::default().build_indexes();
435    /// assert_eq!(f, tskit::TreeSequenceFlags::BUILD_INDEXES);
436    /// ```
437    ///
438    #[derive(Default)]
439    #[repr(transparent)]
440    pub struct TreeSequenceFlags: RawFlags {
441        /// Default behavior
442        const NONE = 0;
443        /// If used, then build table indexes if they are not present.
444        const BUILD_INDEXES = ll_bindings::TSK_TS_INIT_BUILD_INDEXES;
445    }
446}
447
448impl TreeSequenceFlags {
449    flag_builder_api!(
450        /// Set [`BUILD_INDEXES`](crate::TreeSequenceFlags::BUILD_INDEXES)
451        => build_indexes, BUILD_INDEXES);
452}
453
454bitflags! {
455    /// Flags to affect the behavior of
456    /// [`TableCollection::check_integrity`](crate::TableCollection::check_integrity).
457    ///
458    /// # Examples
459    ///
460    /// ## Default (empty) flags
461    ///
462    /// ```
463    /// let f = tskit::TableIntegrityCheckFlags::default();
464    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::NONE);
465    /// ```
466    ///
467    /// ## Builder API
468    ///
469    /// These methods may be chained.
470    ///
471    /// ```
472    /// let f = tskit::TableIntegrityCheckFlags::default().check_edge_ordering();
473    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_EDGE_ORDERING);
474    /// ```
475    ///
476    /// ```
477    /// let f = tskit::TableIntegrityCheckFlags::default().check_site_ordering();
478    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_SITE_ORDERING);
479    /// ```
480    ///
481    /// ```
482    /// let f = tskit::TableIntegrityCheckFlags::default().check_site_duplicates();
483    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_SITE_DUPLICATES);
484    /// ```
485    ///
486    /// ```
487    /// let f = tskit::TableIntegrityCheckFlags::default().check_mutation_ordering();
488    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_MUTATION_ORDERING);
489    /// ```
490    ///
491    /// ```
492    /// let f = tskit::TableIntegrityCheckFlags::default().check_individual_ordering();
493    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_INDIVIDUAL_ORDERING);
494    /// ```
495    ///
496    /// ```
497    /// let f = tskit::TableIntegrityCheckFlags::default().check_migration_ordering();
498    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_MIGRATION_ORDERING);
499    /// ```
500    ///
501    /// ```
502    /// let f = tskit::TableIntegrityCheckFlags::default().check_indexes();
503    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_INDEXES);
504    /// ```
505    ///
506    /// ```
507    /// let f = tskit::TableIntegrityCheckFlags::default().check_trees();
508    /// assert_eq!(f, tskit::TableIntegrityCheckFlags::CHECK_TREES);
509    /// ```
510    #[derive(Default)]
511    #[repr(transparent)]
512    pub struct TableIntegrityCheckFlags: RawFlags {
513        /// Default behavior is a set of basic checks
514        const NONE = 0;
515        /// Check that edges are ordered
516        const CHECK_EDGE_ORDERING =ll_bindings::TSK_CHECK_EDGE_ORDERING;
517        /// Check that sites are ordered
518        const CHECK_SITE_ORDERING =ll_bindings::TSK_CHECK_SITE_ORDERING;
519        /// Check for duplicated sites
520        const CHECK_SITE_DUPLICATES=ll_bindings::TSK_CHECK_SITE_DUPLICATES;
521        /// Check that mutations are ordered
522        const CHECK_MUTATION_ORDERING =ll_bindings::TSK_CHECK_MUTATION_ORDERING;
523        /// Check that individuals are ordered
524        const CHECK_INDIVIDUAL_ORDERING=ll_bindings::TSK_CHECK_INDIVIDUAL_ORDERING;
525        /// Check that migrations are ordered
526        const CHECK_MIGRATION_ORDERING= ll_bindings::TSK_CHECK_MIGRATION_ORDERING;
527        /// Check that table indexes are valid
528        const CHECK_INDEXES=ll_bindings::TSK_CHECK_INDEXES;
529        /// Check tree integrity.  Enables most or all of the preceding options.
530        const CHECK_TREES=ll_bindings::TSK_CHECK_TREES;
531    }
532}
533
534impl TableIntegrityCheckFlags {
535    flag_builder_api!(
536        /// Set [`CHECK_EDGE_ORDERING`](crate::TableIntegrityCheckFlags::CHECK_EDGE_ORDERING)
537        => check_edge_ordering, CHECK_EDGE_ORDERING);
538    flag_builder_api!(
539        /// Set [`CHECK_SITE_ORDERING`](crate::TableIntegrityCheckFlags::CHECK_SITE_ORDERING)
540        => check_site_ordering, CHECK_SITE_ORDERING);
541    flag_builder_api!(
542        /// Set [`CHECK_INDIVIDUAL_ORDERING`](crate::TableIntegrityCheckFlags::CHECK_INDIVIDUAL_ORDERING)
543        => check_individual_ordering, CHECK_INDIVIDUAL_ORDERING);
544    flag_builder_api!(
545        /// Set [`CHECK_MUTATION_ORDERING`](crate::TableIntegrityCheckFlags::CHECK_MUTATION_ORDERING)
546        => check_mutation_ordering, CHECK_MUTATION_ORDERING);
547    flag_builder_api!(
548        /// Set [`CHECK_MIGRATION_ORDERING`](crate::TableIntegrityCheckFlags::CHECK_MIGRATION_ORDERING)
549        => check_migration_ordering, CHECK_MIGRATION_ORDERING);
550    flag_builder_api!(
551        /// Set [`CHECK_SITE_DUPLICATES`](crate::TableIntegrityCheckFlags::CHECK_SITE_DUPLICATES)
552        => check_site_duplicates, CHECK_SITE_DUPLICATES);
553    flag_builder_api!(
554        /// Set [`CHECK_INDEXES`](crate::TableIntegrityCheckFlags::CHECK_INDEXES)
555        => check_indexes, CHECK_INDEXES);
556    flag_builder_api!(
557        /// Set [`CHECK_TREES`](crate::TableIntegrityCheckFlags::CHECK_TREES)
558        => check_trees, CHECK_TREES);
559}
560
561bitflags! {
562    /// Node flags
563    ///
564    /// # Examples
565    ///
566    /// ## Default (empty) flags
567    ///
568    /// ```
569    /// let f = tskit::NodeFlags::default();
570    /// assert_eq!(f, tskit::NodeFlags::NONE);
571    /// ```
572    ///
573    /// ## Create a sample node
574    ///
575    /// Creating a sample node is such a common task that it is supported
576    /// via a constructor:
577    ///
578    /// ```
579    /// let f = tskit::NodeFlags::new_sample();
580    /// assert_eq!(f, tskit::NodeFlags::IS_SAMPLE);
581    /// ```
582    ///
583    /// ## Buider API
584    ///
585    /// These methods can be chained.
586    ///
587    /// ```
588    /// let f = tskit::NodeFlags::default().mark_sample();
589    /// assert_eq!(f, tskit::NodeFlags::IS_SAMPLE);
590    /// ```
591    #[derive(Default)]
592    #[repr(transparent)]
593    pub struct NodeFlags : RawFlags {
594        /// Default (empty)
595        const NONE = 0;
596        /// Node is a sample
597        const IS_SAMPLE = ll_bindings::TSK_NODE_IS_SAMPLE;
598    }
599}
600
601impl NodeFlags {
602    /// Create a new flags instance with `IS_SAMPLE` set.
603    pub fn new_sample() -> Self {
604        Self::default().mark_sample()
605    }
606
607    flag_builder_api!(
608        /// Set [`IS_SAMPLE`](crate::NodeFlags::IS_SAMPLE)
609        ///
610        /// # Note
611        ///
612        /// This function is called `mark_sample` to not conflict
613        /// with [`NodeFlags::is_sample`], which predates it.
614        => mark_sample, IS_SAMPLE);
615
616    /// We do not enforce valid flags in the library.
617    /// This function will return `true` if any bits
618    /// are set that do not correspond to allowed flags.
619    pub fn is_valid(&self) -> bool {
620        true
621    }
622
623    /// Returns `true` if flags contains `IS_SAMPLE`,
624    /// and `false` otherwise.
625    pub fn is_sample(&self) -> bool {
626        self.contains(NodeFlags::IS_SAMPLE)
627    }
628}
629
630bitflags! {
631    #[derive(Default)]
632    #[repr(transparent)]
633    /// Individual flags
634    pub struct IndividualFlags : RawFlags {
635        /// Default (empty)
636        const NONE = 0;
637    }
638}
639
640impl IndividualFlags {
641    /// We do not enforce valid flags in the library.
642    /// This function will return `true` if any bits
643    /// are set that do not correspond to allowed flags.
644    pub fn is_valid(&self) -> bool {
645        true
646    }
647}
648
649impl_flags!(SimplificationOptions);
650impl_flags!(TableClearOptions);
651impl_flags!(TableEqualityOptions);
652impl_flags!(TreeSequenceFlags);
653impl_flags!(TableSortOptions);
654impl_flags!(TreeFlags);
655impl_flags!(IndividualTableSortOptions);
656impl_flags!(TableIntegrityCheckFlags);
657impl_flags!(TableOutputOptions);
658
659impl_from_for_flag_types!(SimplificationOptions);
660impl_from_for_flag_types!(TableClearOptions);
661impl_from_for_flag_types!(TableEqualityOptions);
662impl_from_for_flag_types!(TreeSequenceFlags);
663impl_from_for_flag_types!(TableSortOptions);
664impl_from_for_flag_types!(TreeFlags);
665impl_from_for_flag_types!(IndividualTableSortOptions);
666impl_from_for_flag_types!(TableIntegrityCheckFlags);
667impl_from_for_flag_types!(TableOutputOptions);
668
669impl From<RawFlags> for NodeFlags {
670    fn from(flags: RawFlags) -> Self {
671        // Safety: node flags can contain user-defined values.
672        // It is an error on the user's part to define flags
673        // in the first 16 bits, as per the C API docs.
674        unsafe { Self::from_bits_unchecked(flags) }
675    }
676}
677
678impl From<RawFlags> for IndividualFlags {
679    fn from(flags: RawFlags) -> Self {
680        // Safety: node flags can contain user-defined values.
681        // It is an error on the user's part to define flags
682        // in the first 16 bits, as per the C API docs.
683        unsafe { Self::from_bits_unchecked(flags) }
684    }
685}
686
687#[cfg(test)]
688mod tests {
689    use super::*;
690
691    #[test]
692    fn node_is_not_sample() {
693        let n = NodeFlags::default();
694        assert!(!n.is_sample());
695    }
696
697    #[test]
698    fn node_is_sample() {
699        let n = NodeFlags::new_sample();
700        assert!(n.is_sample());
701    }
702}