Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set/unset flag for mm_mapopt_t/mm_idxopt_t #107

Open
dwpeng opened this issue Dec 7, 2024 · 2 comments
Open

set/unset flag for mm_mapopt_t/mm_idxopt_t #107

dwpeng opened this issue Dec 7, 2024 · 2 comments

Comments

@dwpeng
Copy link
Contributor

dwpeng commented Dec 7, 2024

Hi, @jguhlin, It has been two year when I first learned about this repository. Thanks for you great work on rust binding.

I noticed now minimap2-sys only support use bitor(|) operator to set a flag. This method seems a bit complicated when there are many flags that need to be set. I fork your repository and add a list of method to set/unset flags. If you think this way is Ok, I can pull a request.

diff --git a/minimap2-sys/src/lib.rs b/minimap2-sys/src/lib.rs
index 2540154..194b66a 100644
--- a/minimap2-sys/src/lib.rs
+++ b/minimap2-sys/src/lib.rs
@@ -18,7 +18,6 @@ impl Drop for mm_idx_t {
     }
 }
 
-
 use std::mem::MaybeUninit;
 
 impl Default for mm_mapopt_t {
@@ -31,6 +30,77 @@ impl Default for mm_mapopt_t {
     }
 }
 
+macro_rules! add_flag_methods {
+    ($ty:ty, $struct_name:ident, $(($set_name:ident, $unset_name:ident, $flag:expr)),+) => {
+        impl $struct_name {
+            $(
+                #[inline(always)]
+                pub fn $set_name(mut self) -> Self {
+                    self.flag |= $flag as $ty;
+                    self
+                }
+
+                #[inline(always)]
+                pub fn $unset_name(mut self) -> Self {
+                    self.flag &= !$flag as $ty;
+                    self
+                }
+            )*
+        }
+    };
+}
+
+add_flag_methods!(
+    i64,
+    mm_mapopt_t,
+    (set_no_dual, unset_no_dual, MM_F_NO_DUAL),
+    (set_no_diag, unset_no_diag, MM_F_NO_DIAG),
+    (set_cigar, unset_cigar, MM_F_CIGAR),
+    (set_out_sam, unset_out_sam, MM_F_OUT_SAM),
+    (set_no_qual, unset_no_qual, MM_F_NO_QUAL),
+    (set_out_cg, unset_out_cg, MM_F_OUT_CG),
+    (set_out_cs, unset_out_cs, MM_F_OUT_CS),
+    (set_splice, unset_splice, MM_F_SPLICE),
+    (set_splice_for, unset_splice_for, MM_F_SPLICE_FOR),
+    (set_splice_rev, unset_splice_rev, MM_F_SPLICE_REV),
+    (set_no_ljoin, unset_no_ljoin, MM_F_NO_LJOIN),
+    (set_out_cs_long, unset_out_cs_long, MM_F_OUT_CS_LONG),
+    (set_sr, unset_sr, MM_F_SR),
+    (set_frag_mode, unset_frag_mode, MM_F_FRAG_MODE),
+    (set_no_print_2nd, unset_no_print_2nd, MM_F_NO_PRINT_2ND),
+    (set_two_io_threads, unset_two_io_threads, MM_F_2_IO_THREADS),
+    (set_long_cigar, unset_long_cigar, MM_F_LONG_CIGAR),
+    (set_indep_seg, unset_indep_seg, MM_F_INDEPEND_SEG),
+    (set_splice_flank, unset_splice_flank, MM_F_SPLICE_FLANK),
+    (set_softclip, unset_softclip, MM_F_SOFTCLIP),
+    (set_for_only, unset_for_only, MM_F_FOR_ONLY),
+    (set_rev_only, unset_rev_only, MM_F_REV_ONLY),
+    (set_heap_sort, unset_heap_sort, MM_F_HEAP_SORT),
+    (set_all_chains, unset_all_chains, MM_F_ALL_CHAINS),
+    (set_out_md, unset_out_md, MM_F_OUT_MD),
+    (set_copy_comment, unset_copy_comment, MM_F_COPY_COMMENT),
+    (set_eqx, unset_eqx, MM_F_EQX),
+    (set_paf_no_hit, unset_paf_no_hit, MM_F_PAF_NO_HIT),
+    (set_no_end_flt, unset_no_end_flt, MM_F_NO_END_FLT),
+    (set_hard_mlevel, unset_hard_mlevel, MM_F_HARD_MLEVEL),
+    (set_sam_hit_only, unset_sam_hit_only, MM_F_SAM_HIT_ONLY),
+    (set_rmq, unset_rmq, MM_F_RMQ),
+    (set_qstrand, unset_qstrand, MM_F_QSTRAND),
+    (set_no_inv, unset_no_inv, MM_F_NO_INV),
+    (set_no_hash_name, unset_no_hash_name, MM_F_NO_HASH_NAME),
+    (set_splice_old, unset_splice_old, MM_F_SPLICE_OLD),
+    (set_secondary_seq, unset_secondary_seq, MM_F_SECONDARY_SEQ),
+    (set_out_ds, unset_out_ds, MM_F_OUT_DS)
+);
+
+add_flag_methods!(
+    std::os::raw::c_short,
+    mm_idxopt_t,
+    (set_hpc, unset_hpc, MM_I_HPC),
+    (set_no_seq, unset_no_seq, MM_I_NO_SEQ),
+    (set_no_name, unset_no_name, MM_I_NO_NAME)
+);
+
 impl Default for mm_idxopt_t {
     fn default() -> Self {
         unsafe {
@@ -72,4 +142,24 @@ mod tests {
     fn idxopt() {
         let x: mm_idxopt_t = Default::default();
     }
+
+    #[test]
+    fn test_mapopt_flags() {
+        let mut opt = mm_mapopt_t::default();
+        opt = opt.set_no_qual();
+        assert_eq!(opt.flag & MM_F_NO_QUAL as i64, MM_F_NO_QUAL as i64);
+
+        opt = opt.unset_no_qual();
+        assert_eq!(opt.flag & MM_F_NO_QUAL as i64, 0_i64);
+    }
+
+    #[test]
+    fn test_idxopt_flags() {
+        let mut opt = mm_idxopt_t::default();
+        opt = opt.set_hpc();
+        assert_eq!(opt.flag & MM_I_HPC as i16, MM_I_HPC as i16);
+
+        opt = opt.unset_hpc();
+        assert_eq!(opt.flag & MM_I_HPC as i16, 0_i16);
+    }
 }
@jguhlin
Copy link
Owner

jguhlin commented Dec 9, 2024

Yep, open a PR! Thanks!

@dwpeng
Copy link
Contributor Author

dwpeng commented Dec 9, 2024

@jguhlin , I updated the code by using mut &self instead of self. Because most of the flag settings happen after init aligner. So for an aligner, user can use aligner.mapopt.set_xxx to set/unset flags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants