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}