From ab32755a45418b27da95fe6458a5bc415fa1116c Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:04:50 +0200 Subject: [PATCH 1/8] feat: express thread safety --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b9e0868..375c5f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" authors = ["Manuel Holtgrewe "] description = "Port of biocommons/hgvs to Rust" license = "Apache-2.0" -homepage = "https://github.com/bihealth/seqrepo-rs" +homepage = "https://github.com/bihealth/hgvs-rs" readme = "README.md" rust-version = "1.64.0" @@ -27,7 +27,8 @@ postgres = { version = "0.19", features = ["with-chrono-0_4"] } quick_cache = "0.3" regex = "1.7" rustc-hash = "1.1" -seqrepo = { version = "0.5" } +#seqrepo = { version = "0.5" } +seqrepo = { git = "https://github.com/bihealth/seqrepo-rs.git", branch = "thread-safety" } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } thiserror = "1.0" From c7e1375c2b42237125a59525432c829f433da898 Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:13:48 +0200 Subject: [PATCH 2/8] cleanup --- src/data/cdot/json.rs | 28 ++++++++++++++-------------- src/data/uta.rs | 10 +++++----- src/data/uta_sr.rs | 37 ++++++++++++++++++------------------- src/mapper/assembly.rs | 22 +++++++++++----------- src/mapper/variant.rs | 16 ++++++++-------- src/normalizer.rs | 6 +++--- 6 files changed, 59 insertions(+), 60 deletions(-) diff --git a/src/data/cdot/json.rs b/src/data/cdot/json.rs index 8264356..ae29d19 100644 --- a/src/data/cdot/json.rs +++ b/src/data/cdot/json.rs @@ -7,8 +7,8 @@ use std::{collections::HashMap, path::PathBuf, rc::Rc, time::Instant}; use crate::{ data::error::Error, data::interface::{ - GeneInfoRecord, Provider as ProviderInterface, TxExonsRecord, TxForRegionRecord, - TxIdentityInfo, TxInfoRecord, TxMappingOptionsRecord, TxSimilarityRecord, + self, GeneInfoRecord, TxExonsRecord, TxForRegionRecord, TxIdentityInfo, TxInfoRecord, + TxMappingOptionsRecord, TxSimilarityRecord, }, static_data::{Assembly, ASSEMBLY_INFOS}, }; @@ -16,7 +16,7 @@ use crate::{ use bio::data_structures::interval_tree::ArrayBackedIntervalTree; use chrono::NaiveDateTime; use indexmap::IndexMap; -use seqrepo::{Interface as SeqRepoInterface, SeqRepo}; +use seqrepo::{self, SeqRepo}; /// Configurationf or the `data::cdot::Provider`. #[derive(Debug, PartialEq, Clone)] @@ -42,7 +42,7 @@ pub struct Config { /// `exon_aln_id`. pub struct Provider { inner: TxProvider, - seqrepo: Rc, + seqrepo: Rc, } impl Provider { @@ -77,7 +77,7 @@ impl Provider { /// Create a new provider allowing to inject a seqrepo. pub fn with_seqrepo( config: Config, - seqrepo: Rc, + seqrepo: Rc, ) -> Result { Ok(Self { inner: TxProvider::with_config( @@ -93,7 +93,7 @@ impl Provider { } } -impl ProviderInterface for Provider { +impl interface::Provider for Provider { fn data_version(&self) -> &str { self.inner.data_version() } @@ -699,7 +699,7 @@ pub static REQUIRED_VERSION: &str = "1.1"; /// The alignment method returned for all cdot transcripts. pub static NCBI_ALN_METHOD: &str = "splign"; -/// Implementation for `ProviderInterface`. +/// Implementation for `interface::Provider`. impl TxProvider { fn data_version(&self) -> &str { REQUIRED_VERSION @@ -1029,7 +1029,7 @@ pub mod test_helpers { use crate::data::uta_sr::test_helpers::build_writing_sr; use super::{Config, Provider}; - use seqrepo::{CacheReadingSeqRepo, Interface as SeqRepoInterface}; + use seqrepo; pub fn build_provider() -> Result { let sr_cache_mode = std::env::var("TEST_SEQREPO_CACHE_MODE") @@ -1040,8 +1040,8 @@ pub mod test_helpers { log::debug!("building provider..."); let seqrepo = if sr_cache_mode == "read" { log::debug!("reading provider..."); - let seqrepo: Rc = - Rc::new(CacheReadingSeqRepo::new(sr_cache_path)?); + let seqrepo: Rc = + Rc::new(seqrepo::CacheReadingSeqRepo::new(sr_cache_path)?); log::debug!("construction done..."); seqrepo } else if sr_cache_mode == "write" { @@ -1076,10 +1076,10 @@ pub mod tests { use super::models::{gap_to_cigar, Container}; use super::test_helpers::build_provider; use crate::data::interface::{ - GeneInfoRecord, Provider as ProviderInterface, TxExonsRecord, TxForRegionRecord, - TxInfoRecord, TxMappingOptionsRecord, TxSimilarityRecord, + GeneInfoRecord, Provider, TxExonsRecord, TxForRegionRecord, TxInfoRecord, + TxMappingOptionsRecord, TxSimilarityRecord, }; - use crate::mapper::assembly::{Config as AssemblyMapperConfig, Mapper}; + use crate::mapper::assembly::{self, Mapper}; use crate::parser::HgvsVariant; use crate::static_data::Assembly; @@ -2153,7 +2153,7 @@ pub mod tests { fn build_mapper_37(normalize: bool) -> Result { let provider = Rc::new(build_provider()?); - let config = AssemblyMapperConfig { + let config = assembly::Config { assembly: Assembly::Grch37, normalize, ..Default::default() diff --git a/src/data/uta.rs b/src/data/uta.rs index d40ae19..fe8eccc 100644 --- a/src/data/uta.rs +++ b/src/data/uta.rs @@ -12,9 +12,9 @@ use crate::sequences::seq_md5; use crate::static_data::{Assembly, ASSEMBLY_INFOS}; use crate::data::{ - error::Error, interface::GeneInfoRecord, interface::Provider as ProviderInterface, - interface::TxExonsRecord, interface::TxForRegionRecord, interface::TxIdentityInfo, - interface::TxInfoRecord, interface::TxMappingOptionsRecord, interface::TxSimilarityRecord, + error::Error, interface, interface::GeneInfoRecord, interface::TxExonsRecord, + interface::TxForRegionRecord, interface::TxIdentityInfo, interface::TxInfoRecord, + interface::TxMappingOptionsRecord, interface::TxSimilarityRecord, }; /// Configuration for the `data::uta::Provider`. @@ -234,7 +234,7 @@ impl Provider { } } -impl ProviderInterface for Provider { +impl interface::Provider for Provider { fn data_version(&self) -> &str { &self.config.db_schema } @@ -604,7 +604,7 @@ impl ProviderInterface for Provider { #[cfg(test)] mod test { - use crate::{data::interface::Provider as ProviderInterface, static_data::Assembly}; + use crate::{data::interface::Provider as InterfaceProvider, static_data::Assembly}; use anyhow::Error; use super::{Config, Provider}; diff --git a/src/data/uta_sr.rs b/src/data/uta_sr.rs index b2787ba..70fc402 100644 --- a/src/data/uta_sr.rs +++ b/src/data/uta_sr.rs @@ -7,13 +7,13 @@ use std::path::PathBuf; use std::rc::Rc; -use crate::data::uta::{Config as UtaConfig, Provider as UtaProvider}; +use crate::data::uta; use crate::data::{ - error::Error, interface::GeneInfoRecord, interface::Provider as ProviderInterface, - interface::TxExonsRecord, interface::TxForRegionRecord, interface::TxIdentityInfo, - interface::TxInfoRecord, interface::TxMappingOptionsRecord, interface::TxSimilarityRecord, + error::Error, interface, interface::GeneInfoRecord, interface::TxExonsRecord, + interface::TxForRegionRecord, interface::TxIdentityInfo, interface::TxInfoRecord, + interface::TxMappingOptionsRecord, interface::TxSimilarityRecord, }; -use seqrepo::{AliasOrSeqId, Interface as SeqRepoInterface, SeqRepo}; +use seqrepo::{self, AliasOrSeqId, SeqRepo}; /// Configuration for the `data::uta_sr::Provider`. #[derive(Debug, PartialEq, Clone)] @@ -33,8 +33,8 @@ pub struct Config { /// Transcripts from a UTA Postgres database, sequences comes from a SeqRepo. This makes /// genome contig information available in contrast to `data::uta::Provider`. pub struct Provider { - inner: UtaProvider, - seqrepo: Rc, + inner: uta::Provider, + seqrepo: Rc, } impl Provider { @@ -58,7 +58,7 @@ impl Provider { .to_string(); Ok(Self { - inner: UtaProvider::with_config(&UtaConfig { + inner: uta::Provider::with_config(&uta::Config { db_url: config.db_url.clone(), db_schema: config.db_schema, })?, @@ -69,10 +69,10 @@ impl Provider { /// Create a new provider allowing to inject a seqrepo. pub fn with_seqrepo( config: Config, - seqrepo: Rc, + seqrepo: Rc, ) -> Result { Ok(Self { - inner: UtaProvider::with_config(&UtaConfig { + inner: uta::Provider::with_config(&uta::Config { db_url: config.db_url.clone(), db_schema: config.db_schema, })?, @@ -81,7 +81,7 @@ impl Provider { } } -impl ProviderInterface for Provider { +impl interface::Provider for Provider { fn data_version(&self) -> &str { self.inner.data_version() } @@ -174,18 +174,17 @@ impl ProviderInterface for Provider { #[cfg(test)] pub mod test_helpers { use anyhow::Error; + use seqrepo::{CacheReadingSeqRepo, CacheWritingSeqRepo, SeqRepo}; use std::{path::PathBuf, rc::Rc}; - use seqrepo::{ - CacheReadingSeqRepo, CacheWritingSeqRepo, Interface as SeqRepoInterface, SeqRepo, - }; + use crate::data::interface; - use super::{Config, Provider, ProviderInterface}; + use super::{Config, Provider}; /// Setup a UTA Provider with data source depending on environment variables. /// /// See README.md for information on environment variable setup. - pub fn build_provider() -> Result, Error> { + pub fn build_provider() -> Result, Error> { log::debug!("building provider..."); let db_url = std::env::var("TEST_UTA_DATABASE_URL") .expect("Environment variable TEST_UTA_DATABASE_URL undefined!"); @@ -198,7 +197,7 @@ pub mod test_helpers { let (seqrepo, seqrepo_path) = if sr_cache_mode == "read" { log::debug!("reading provider..."); - let seqrepo: Rc = + let seqrepo: Rc = Rc::new(CacheReadingSeqRepo::new(sr_cache_path)?); log::debug!("construction done..."); (seqrepo, "".to_string()) @@ -223,7 +222,7 @@ pub mod test_helpers { /// Helper that builds the cache writing SeqRepo with inner stock SeqRepo. pub fn build_writing_sr( sr_cache_path: String, - ) -> Result<(Rc, String), Error> { + ) -> Result<(Rc, String), Error> { let seqrepo_path = std::env::var("TEST_SEQREPO_PATH") .expect("Environment variable TEST_SEQREPO_PATH undefined!"); let path_buf = PathBuf::from(seqrepo_path.clone()); @@ -245,7 +244,7 @@ pub mod test_helpers { .to_str() .expect("problem with path to string conversion") .to_string(); - let seqrepo: Rc = Rc::new(CacheWritingSeqRepo::new( + let seqrepo: Rc = Rc::new(CacheWritingSeqRepo::new( SeqRepo::new(path, &instance)?, sr_cache_path, )?); diff --git a/src/mapper/assembly.rs b/src/mapper/assembly.rs index 1448a01..d37c4df 100644 --- a/src/mapper/assembly.rs +++ b/src/mapper/assembly.rs @@ -5,7 +5,7 @@ use std::ops::Range; use std::rc::Rc; use crate::mapper::error::Error; -use crate::mapper::variant::{Config as VariantMapperConfig, Mapper as VariantMapper}; +use crate::mapper::variant; use crate::parser::HgvsVariant; use crate::{data::interface::Provider, static_data::Assembly, validator::ValidationLevel}; @@ -68,7 +68,7 @@ impl Default for Config { /// Provides simplified variant mapping for a single assembly and transcript-reference /// alignment method. /// -/// `AssemblyMapper` uses `VariantMapper`, to provide all projection functionality, and add: +/// `AssemblyMapper` uses `variant::Mapper`, to provide all projection functionality, and add: /// /// * Automatic selection of genomic sequence accession /// * Transcript selection from genomic coordinates @@ -76,7 +76,7 @@ impl Default for Config { /// * Special handling for PAR regions /// /// `AssemblyMapper` is instantiated with an assembly name and `alt_aln_method`. These enable -/// the following conveniences over `VariantMapper`: +/// the following conveniences over `variant::Mapper`: /// /// * The assembly and alignment method are used to automatically select an appropriate /// chromosomal reference sequence when mapping from a transcript to a genome (i.e., @@ -91,7 +91,7 @@ impl Default for Config { pub struct Mapper { config: Config, provider: Rc, - inner: VariantMapper, + inner: variant::Mapper, /// Accessions of contigs in assembly. asm_accessions: HashSet, /// Map from accession to contig name. @@ -101,7 +101,7 @@ pub struct Mapper { impl Mapper { /// Construct new assembly mapper from config and provider. pub fn new(config: Config, provider: Rc) -> Self { - let inner_config = VariantMapperConfig { + let inner_config = variant::Config { replace_reference: config.replace_reference, strict_validation: config.strict_validation, prevalidation_level: config.prevalidation_level, @@ -110,7 +110,7 @@ impl Mapper { renormalize_g: config.renormalize_g, genome_seq_available: config.genome_seq_available, }; - let inner = VariantMapper::new(&inner_config, provider.clone()); + let inner = variant::Mapper::new(&inner_config, provider.clone()); let asm_accessions = provider .as_ref() .get_assembly_map(config.assembly) @@ -403,8 +403,8 @@ mod test { Ok(()) } - /// The following is a port of `Test_VariantMapper` in - /// `test_hgvs_variantmapper_near_discrepancies.py` (sic!) + /// The following is a port of `Test_variant::Mapper` in + /// `test_hgvs_variant::Mapper_near_discrepancies.py` (sic!) mod cases { use anyhow::Error; use std::str::FromStr; @@ -605,7 +605,7 @@ mod test { } /// The following is a port of the `Test_RefReplacement` in - /// `test_hgvs_variantmapper_near_discrepancies.py` (sic!) + /// `test_hgvs_variant::Mapper_near_discrepancies.py` (sic!) mod ref_replacement { use anyhow::Error; use std::str::FromStr; @@ -864,7 +864,7 @@ mod test { } /// The following is a port of `Test_AssemblyMapper` in - /// `test_hgvs_variantmapper_near_discrepancies.py` (sic!) + /// `test_hgvs_variant::Mapper_near_discrepancies.py` (sic!) mod projections { use anyhow::Error; use std::str::FromStr; @@ -930,7 +930,7 @@ mod test { } } - /// The following is a port of the `test_hgvs_variantmapper_near_discrepancies.py` (sic!) + /// The following is a port of the `test_hgvs_variant::Mapper_near_discrepancies.py` (sic!) mod near_discrepancies { use anyhow::Error; use std::str::FromStr; diff --git a/src/mapper/variant.rs b/src/mapper/variant.rs index 4128140..fea01d0 100644 --- a/src/mapper/variant.rs +++ b/src/mapper/variant.rs @@ -4,11 +4,11 @@ use std::{ops::Range, rc::Rc}; use log::{debug, info}; -use super::alignment::{Config as AlignmentConfig, Mapper as AlignmentMapper}; +use super::alignment; use crate::{ data::interface::Provider, mapper::Error, - normalizer::{self, Config as NormalizerConfig, Normalizer}, + normalizer::{self, Normalizer}, parser::{ Accession, CdsInterval, CdsLocEdit, CdsPos, GeneSymbol, GenomeInterval, GenomeLocEdit, HgvsVariant, Mu, NaEdit, TxInterval, TxLocEdit, TxPos, @@ -120,10 +120,10 @@ impl Mapper { tx_ac: &str, alt_ac: &str, alt_aln_method: &str, - ) -> Result { + ) -> Result { // TODO: implement caching - AlignmentMapper::new( - &AlignmentConfig { + alignment::Mapper::new( + &alignment::Config { strict_bounds: self.config.strict_bounds, }, self.provider.clone(), @@ -139,7 +139,7 @@ impl Mapper { self, self.provider.clone(), self.validator.clone(), - NormalizerConfig { + normalizer::Config { replace_reference: self.config.replace_reference, ..Default::default() }, @@ -1088,7 +1088,7 @@ mod test { rc::Rc, }; - use crate::data::interface::Provider as ProviderInterface; + use crate::data::interface; use crate::{ data::interface::TxIdentityInfo, mapper::variant::{Config, Mapper}, @@ -1122,7 +1122,7 @@ mod test { } } - impl ProviderInterface for Provider { + impl interface::Provider for Provider { fn data_version(&self) -> &str { panic!("for test use only"); } diff --git a/src/normalizer.rs b/src/normalizer.rs index a02a398..0c21d65 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -5,7 +5,7 @@ use std::{cmp::Ordering, ops::Range, rc::Rc}; pub use crate::normalizer::error::Error; use crate::{ data::interface::Provider, - mapper::variant::Mapper as VariantMapper, + mapper::variant, parser::{ GenomeInterval, GenomeLocEdit, HgvsVariant, MtInterval, MtLocEdit, Mu, NaEdit, RnaInterval, RnaLocEdit, RnaPos, TxInterval, TxLocEdit, TxPos, @@ -90,7 +90,7 @@ pub struct Normalizer<'a> { pub provider: Rc, pub validator: Rc, pub config: Config, - pub mapper: &'a VariantMapper, + pub mapper: &'a variant::Mapper, } /// Helper type used in `Normalizer::check_and_guard()`. @@ -102,7 +102,7 @@ struct CheckAndGuardResult { impl<'a> Normalizer<'a> { pub fn new( - mapper: &'a VariantMapper, + mapper: &'a variant::Mapper, provider: Rc, validator: Rc, config: Config, From 5a58fb1edb04a931e5402575ced4d383330e2283 Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:30:17 +0200 Subject: [PATCH 3/8] wip --- src/data/cdot/json.rs | 20 +++++++++++++------- src/data/uta.rs | 6 ++++++ src/data/uta_sr.rs | 33 +++++++++++++++++++-------------- src/mapper/alignment.rs | 12 +++++++++--- src/mapper/altseq.rs | 4 ++-- src/mapper/assembly.rs | 5 +++-- src/mapper/variant.rs | 10 +++++----- src/normalizer.rs | 12 ++++++------ src/validator/mod.rs | 18 +++++++++++------- 9 files changed, 74 insertions(+), 46 deletions(-) diff --git a/src/data/cdot/json.rs b/src/data/cdot/json.rs index ae29d19..23b7d68 100644 --- a/src/data/cdot/json.rs +++ b/src/data/cdot/json.rs @@ -2,7 +2,7 @@ //! //! https://github.com/SACGF/cdot -use std::{collections::HashMap, path::PathBuf, rc::Rc, time::Instant}; +use std::{collections::HashMap, path::PathBuf, sync::Arc, time::Instant}; use crate::{ data::error::Error, @@ -42,7 +42,7 @@ pub struct Config { /// `exon_aln_id`. pub struct Provider { inner: TxProvider, - seqrepo: Rc, + seqrepo: Arc, } impl Provider { @@ -70,14 +70,14 @@ impl Provider { .collect::>() .as_ref(), )?, - seqrepo: Rc::new(SeqRepo::new(path, &instance)?), + seqrepo: Arc::new(SeqRepo::new(path, &instance)?), }) } /// Create a new provider allowing to inject a seqrepo. pub fn with_seqrepo( config: Config, - seqrepo: Rc, + seqrepo: Arc, ) -> Result { Ok(Self { inner: TxProvider::with_config( @@ -1024,7 +1024,7 @@ impl TxProvider { #[cfg(test)] pub mod test_helpers { use anyhow::Error; - use std::rc::Rc; + use std::sync::Arc; use crate::data::uta_sr::test_helpers::build_writing_sr; @@ -1040,8 +1040,8 @@ pub mod test_helpers { log::debug!("building provider..."); let seqrepo = if sr_cache_mode == "read" { log::debug!("reading provider..."); - let seqrepo: Rc = - Rc::new(seqrepo::CacheReadingSeqRepo::new(sr_cache_path)?); + let seqrepo: Arc = + Arc::new(seqrepo::CacheReadingSeqRepo::new(sr_cache_path)?); log::debug!("construction done..."); seqrepo } else if sr_cache_mode == "write" { @@ -1083,6 +1083,12 @@ pub mod tests { use crate::parser::HgvsVariant; use crate::static_data::Assembly; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + #[test] fn deserialize_brca1() -> Result<(), Error> { let json = std::fs::read_to_string( diff --git a/src/data/uta.rs b/src/data/uta.rs index fe8eccc..e9d7657 100644 --- a/src/data/uta.rs +++ b/src/data/uta.rs @@ -609,6 +609,12 @@ mod test { use super::{Config, Provider}; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + fn get_config() -> Config { Config { db_url: std::env::var("TEST_UTA_DATABASE_URL") diff --git a/src/data/uta_sr.rs b/src/data/uta_sr.rs index 70fc402..f12fcea 100644 --- a/src/data/uta_sr.rs +++ b/src/data/uta_sr.rs @@ -5,7 +5,7 @@ //! * https://github.com/bihealth/seqrepo-rs use std::path::PathBuf; -use std::rc::Rc; +use std::sync::Arc; use crate::data::uta; use crate::data::{ @@ -34,7 +34,7 @@ pub struct Config { /// genome contig information available in contrast to `data::uta::Provider`. pub struct Provider { inner: uta::Provider, - seqrepo: Rc, + seqrepo: Arc, } impl Provider { @@ -62,14 +62,14 @@ impl Provider { db_url: config.db_url.clone(), db_schema: config.db_schema, })?, - seqrepo: Rc::new(SeqRepo::new(path, &instance)?), + seqrepo: Arc::new(SeqRepo::new(path, &instance)?), }) } /// Create a new provider allowing to inject a seqrepo. pub fn with_seqrepo( config: Config, - seqrepo: Rc, + seqrepo: Arc, ) -> Result { Ok(Self { inner: uta::Provider::with_config(&uta::Config { @@ -175,16 +175,22 @@ impl interface::Provider for Provider { pub mod test_helpers { use anyhow::Error; use seqrepo::{CacheReadingSeqRepo, CacheWritingSeqRepo, SeqRepo}; - use std::{path::PathBuf, rc::Rc}; + use std::{path::PathBuf, sync::Arc}; use crate::data::interface; use super::{Config, Provider}; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + /// Setup a UTA Provider with data source depending on environment variables. /// /// See README.md for information on environment variable setup. - pub fn build_provider() -> Result, Error> { + pub fn build_provider() -> Result, Error> { log::debug!("building provider..."); let db_url = std::env::var("TEST_UTA_DATABASE_URL") .expect("Environment variable TEST_UTA_DATABASE_URL undefined!"); @@ -197,8 +203,8 @@ pub mod test_helpers { let (seqrepo, seqrepo_path) = if sr_cache_mode == "read" { log::debug!("reading provider..."); - let seqrepo: Rc = - Rc::new(CacheReadingSeqRepo::new(sr_cache_path)?); + let seqrepo: Arc = + Arc::new(CacheReadingSeqRepo::new(sr_cache_path)?); log::debug!("construction done..."); (seqrepo, "".to_string()) } else if sr_cache_mode == "write" { @@ -209,7 +215,7 @@ pub mod test_helpers { }; log::debug!("now returning provider..."); - Ok(Rc::new(Provider::with_seqrepo( + Ok(Arc::new(Provider::with_seqrepo( Config { db_url, db_schema, @@ -222,7 +228,7 @@ pub mod test_helpers { /// Helper that builds the cache writing SeqRepo with inner stock SeqRepo. pub fn build_writing_sr( sr_cache_path: String, - ) -> Result<(Rc, String), Error> { + ) -> Result<(Arc, String), Error> { let seqrepo_path = std::env::var("TEST_SEQREPO_PATH") .expect("Environment variable TEST_SEQREPO_PATH undefined!"); let path_buf = PathBuf::from(seqrepo_path.clone()); @@ -244,10 +250,9 @@ pub mod test_helpers { .to_str() .expect("problem with path to string conversion") .to_string(); - let seqrepo: Rc = Rc::new(CacheWritingSeqRepo::new( - SeqRepo::new(path, &instance)?, - sr_cache_path, - )?); + let seqrepo: Arc = Arc::new( + CacheWritingSeqRepo::new(SeqRepo::new(path, &instance)?, sr_cache_path)?, + ); Ok((seqrepo, seqrepo_path)) } } diff --git a/src/mapper/alignment.rs b/src/mapper/alignment.rs index d442671..3456b76 100644 --- a/src/mapper/alignment.rs +++ b/src/mapper/alignment.rs @@ -22,7 +22,7 @@ // n. -2 -1 ! 1 2 3 4 5 6 7 8 9 // g. ... 123 124 125 126 127 128 129 130 131 132 133 ... -use std::rc::Rc; +use std::sync::Arc; use crate::{ data::interface::{Provider, TxExonsRecord}, @@ -119,7 +119,7 @@ pub struct Mapper { /// Configuration for alignment mapping. pub config: Config, /// Data provider to use for the mapping. - pub provider: Rc, + pub provider: Arc, /// The transcript accession. pub tx_ac: String, @@ -138,7 +138,7 @@ pub struct Mapper { impl Mapper { pub fn new( config: &Config, - provider: Rc, + provider: Arc, tx_ac: &str, alt_ac: &str, alt_aln_method: &str, @@ -499,6 +499,12 @@ mod test { use super::{build_tx_cigar, none_if_default, Mapper}; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + #[test] fn build_tx_cigar_empty() { assert!(build_tx_cigar(&Vec::new(), 1).is_err()); diff --git a/src/mapper/altseq.rs b/src/mapper/altseq.rs index 3a0036c..68d6497 100644 --- a/src/mapper/altseq.rs +++ b/src/mapper/altseq.rs @@ -1,6 +1,6 @@ //! Code for building alternative sequence and convertion to HGVS.p. -use std::{cmp::Ordering, rc::Rc}; +use std::{cmp::Ordering, rc::Rc, sync::Arc}; use crate::{ data::interface::Provider, @@ -35,7 +35,7 @@ impl RefTranscriptData { /// * `tx_ac` -- Transcript accession. /// * `pro_ac` -- Protein accession. pub fn new( - provider: Rc, + provider: Arc, tx_ac: &str, pro_ac: Option<&str>, ) -> Result { diff --git a/src/mapper/assembly.rs b/src/mapper/assembly.rs index d37c4df..d93db5d 100644 --- a/src/mapper/assembly.rs +++ b/src/mapper/assembly.rs @@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet}; use std::ops::Range; use std::rc::Rc; +use std::sync::Arc; use crate::mapper::error::Error; use crate::mapper::variant; @@ -90,7 +91,7 @@ impl Default for Config { /// not support contigs or other genomic sequences (e.g., NT_167249.1). pub struct Mapper { config: Config, - provider: Rc, + provider: Arc, inner: variant::Mapper, /// Accessions of contigs in assembly. asm_accessions: HashSet, @@ -100,7 +101,7 @@ pub struct Mapper { impl Mapper { /// Construct new assembly mapper from config and provider. - pub fn new(config: Config, provider: Rc) -> Self { + pub fn new(config: Config, provider: Arc) -> Self { let inner_config = variant::Config { replace_reference: config.replace_reference, strict_validation: config.strict_validation, diff --git a/src/mapper/variant.rs b/src/mapper/variant.rs index fea01d0..9cb3a34 100644 --- a/src/mapper/variant.rs +++ b/src/mapper/variant.rs @@ -1,6 +1,6 @@ //! Code for mapping variants between sequences. -use std::{ops::Range, rc::Rc}; +use std::{ops::Range, rc::Rc, sync::Arc}; use log::{debug, info}; @@ -53,8 +53,8 @@ impl Default for Config { /// Projects variants between sequences using `alignment::Mapper`. pub struct Mapper { config: Config, - provider: Rc, - validator: Rc, + provider: Arc, + validator: Arc, } /// Maps SequenceVariant objects between g., n., r., c., and p. representations. @@ -91,7 +91,7 @@ pub struct Mapper { /// differences. For example, c_to_g accounts for the transcription /// start site offset, then calls n_to_g. impl Mapper { - pub fn new(config: &Config, provider: Rc) -> Mapper { + pub fn new(config: &Config, provider: Arc) -> Mapper { let validator = config .prevalidation_level .validator(config.strict_validation, provider.clone()); @@ -110,7 +110,7 @@ impl Mapper { } /// Return a copy of the internal provider. - pub fn provider(&self) -> Rc { + pub fn provider(&self) -> Arc { self.provider.clone() } diff --git a/src/normalizer.rs b/src/normalizer.rs index 0c21d65..d55b7c2 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -1,6 +1,6 @@ //! Variant normalization. -use std::{cmp::Ordering, ops::Range, rc::Rc}; +use std::{cmp::Ordering, ops::Range, rc::Rc, sync::Arc}; pub use crate::normalizer::error::Error; use crate::{ @@ -87,8 +87,8 @@ impl Default for Config { /// Normalizes variants (5' and 3' shifting). pub struct Normalizer<'a> { - pub provider: Rc, - pub validator: Rc, + pub provider: Arc, + pub validator: Arc, pub config: Config, pub mapper: &'a variant::Mapper, } @@ -103,8 +103,8 @@ struct CheckAndGuardResult { impl<'a> Normalizer<'a> { pub fn new( mapper: &'a variant::Mapper, - provider: Rc, - validator: Rc, + provider: Arc, + validator: Arc, config: Config, ) -> Self { Self { @@ -1059,7 +1059,7 @@ mod test { mapper: &Mapper, ) -> Result<(Normalizer, Normalizer, Normalizer, Normalizer), Error> { let provider = mapper.provider(); - let validator = Rc::new(IntrinsicValidator::new(true)); + let validator = Arc::new(IntrinsicValidator::new(true)); Ok(( Normalizer::new( diff --git a/src/validator/mod.rs b/src/validator/mod.rs index 9f273ea..29a2259 100644 --- a/src/validator/mod.rs +++ b/src/validator/mod.rs @@ -2,7 +2,7 @@ mod error; -use std::rc::Rc; +use std::{rc::Rc, sync::Arc}; use log::{error, warn}; @@ -30,11 +30,15 @@ pub enum ValidationLevel { } impl ValidationLevel { - pub fn validator(&self, strict: bool, provider: Rc) -> Rc { + pub fn validator( + &self, + strict: bool, + provider: Arc, + ) -> Arc { match self { - ValidationLevel::Null => Rc::new(NullValidator::new()), - ValidationLevel::Intrinsic => Rc::new(IntrinsicValidator::new(strict)), - ValidationLevel::Full => Rc::new(FullValidator::new(strict, provider)), + ValidationLevel::Null => Arc::new(NullValidator::new()), + ValidationLevel::Intrinsic => Arc::new(IntrinsicValidator::new(strict)), + ValidationLevel::Full => Arc::new(FullValidator::new(strict, provider)), } } } @@ -121,7 +125,7 @@ pub struct ExtrinsicValidator { } impl ExtrinsicValidator { - pub fn new(strict: bool, provider: Rc) -> Self { + pub fn new(strict: bool, provider: Arc) -> Self { let config = Config { replace_reference: false, strict_validation: false, @@ -211,7 +215,7 @@ pub struct FullValidator { } impl FullValidator { - pub fn new(strict: bool, provider: Rc) -> Self { + pub fn new(strict: bool, provider: Arc) -> Self { Self { intrinsic: IntrinsicValidator::new(strict), extrinsic: ExtrinsicValidator::new(strict, provider), From 6e7084572977dbdd344a7bf49d2c0c738f205abe Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:32:55 +0200 Subject: [PATCH 4/8] wip --- src/data/cdot/json.rs | 3 ++- src/mapper/altseq.rs | 2 +- src/mapper/assembly.rs | 2 +- src/mapper/variant.rs | 6 +++--- src/normalizer.rs | 4 ++-- src/validator/mod.rs | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/data/cdot/json.rs b/src/data/cdot/json.rs index 23b7d68..6253445 100644 --- a/src/data/cdot/json.rs +++ b/src/data/cdot/json.rs @@ -1068,6 +1068,7 @@ pub mod tests { use anyhow::Error; use std::rc::Rc; use std::str::FromStr; + use std::sync::Arc; use chrono::NaiveDateTime; use pretty_assertions::assert_eq; @@ -2158,7 +2159,7 @@ pub mod tests { } fn build_mapper_37(normalize: bool) -> Result { - let provider = Rc::new(build_provider()?); + let provider = Arc::new(build_provider()?); let config = assembly::Config { assembly: Assembly::Grch37, normalize, diff --git a/src/mapper/altseq.rs b/src/mapper/altseq.rs index 68d6497..0ad9585 100644 --- a/src/mapper/altseq.rs +++ b/src/mapper/altseq.rs @@ -1,6 +1,6 @@ //! Code for building alternative sequence and convertion to HGVS.p. -use std::{cmp::Ordering, rc::Rc, sync::Arc}; +use std::{cmp::Ordering, sync::Arc}; use crate::{ data::interface::Provider, diff --git a/src/mapper/assembly.rs b/src/mapper/assembly.rs index d93db5d..72475c4 100644 --- a/src/mapper/assembly.rs +++ b/src/mapper/assembly.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use std::ops::Range; -use std::rc::Rc; + use std::sync::Arc; use crate::mapper::error::Error; diff --git a/src/mapper/variant.rs b/src/mapper/variant.rs index 9cb3a34..0584a7a 100644 --- a/src/mapper/variant.rs +++ b/src/mapper/variant.rs @@ -1,6 +1,6 @@ //! Code for mapping variants between sequences. -use std::{ops::Range, rc::Rc, sync::Arc}; +use std::{ops::Range, sync::Arc}; use log::{debug, info}; @@ -1085,7 +1085,7 @@ mod test { use anyhow::Error; use std::{ path::{Path, PathBuf}, - rc::Rc, + rc::Rc, sync::Arc, }; use crate::data::interface; @@ -1264,7 +1264,7 @@ mod test { pub fn build_mapper(strict_bounds: bool) -> Result { let path = PathBuf::from("tests/data/mapper/sanity_cp.tsv"); - let provider = Rc::new(Provider::new(&path)?); + let provider = Arc::new(Provider::new(&path)?); let config = Config { strict_bounds, ..Default::default() diff --git a/src/normalizer.rs b/src/normalizer.rs index d55b7c2..19449b4 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -1,6 +1,6 @@ //! Variant normalization. -use std::{cmp::Ordering, ops::Range, rc::Rc, sync::Arc}; +use std::{cmp::Ordering, ops::Range, sync::Arc}; pub use crate::normalizer::error::Error; use crate::{ @@ -1043,7 +1043,7 @@ mod test { use test_log::test; use anyhow::Error; - use std::{rc::Rc, str::FromStr}; + use std::{rc::Rc, str::FromStr, sync::Arc}; use pretty_assertions::assert_eq; diff --git a/src/validator/mod.rs b/src/validator/mod.rs index 29a2259..81e6a77 100644 --- a/src/validator/mod.rs +++ b/src/validator/mod.rs @@ -2,7 +2,7 @@ mod error; -use std::{rc::Rc, sync::Arc}; +use std::sync::Arc; use log::{error, warn}; From 4a34d1f99dc477eb8921fd94694c8039b568ab7d Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:33:18 +0200 Subject: [PATCH 5/8] wip --- src/data/cdot/json.rs | 2 +- src/mapper/variant.rs | 2 +- src/normalizer.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/cdot/json.rs b/src/data/cdot/json.rs index 6253445..12ae1f8 100644 --- a/src/data/cdot/json.rs +++ b/src/data/cdot/json.rs @@ -1066,7 +1066,7 @@ pub mod test_helpers { #[cfg(test)] pub mod tests { use anyhow::Error; - use std::rc::Rc; + use std::str::FromStr; use std::sync::Arc; diff --git a/src/mapper/variant.rs b/src/mapper/variant.rs index 0584a7a..64e1f98 100644 --- a/src/mapper/variant.rs +++ b/src/mapper/variant.rs @@ -1085,7 +1085,7 @@ mod test { use anyhow::Error; use std::{ path::{Path, PathBuf}, - rc::Rc, sync::Arc, + sync::Arc, }; use crate::data::interface; diff --git a/src/normalizer.rs b/src/normalizer.rs index 19449b4..9a5a2ee 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -1043,7 +1043,7 @@ mod test { use test_log::test; use anyhow::Error; - use std::{rc::Rc, str::FromStr, sync::Arc}; + use std::{str::FromStr, sync::Arc}; use pretty_assertions::assert_eq; From 79cc8d4eaa135eba669a7bd2f1a1440992359342 Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:37:22 +0200 Subject: [PATCH 6/8] more is sync tests --- src/mapper/assembly.rs | 6 ++++++ src/mapper/variant.rs | 6 ++++++ src/normalizer.rs | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/src/mapper/assembly.rs b/src/mapper/assembly.rs index 72475c4..586b32b 100644 --- a/src/mapper/assembly.rs +++ b/src/mapper/assembly.rs @@ -378,6 +378,12 @@ mod test { use super::{Config, Mapper}; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + fn build_mapper_38(normalize: bool) -> Result { let provider = build_provider()?; let config = Config { diff --git a/src/mapper/variant.rs b/src/mapper/variant.rs index 64e1f98..a57b44e 100644 --- a/src/mapper/variant.rs +++ b/src/mapper/variant.rs @@ -959,6 +959,12 @@ mod test { use super::{Config, Mapper}; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + fn build_mapper() -> Result { let provider = build_provider()?; let config = Config::default(); diff --git a/src/normalizer.rs b/src/normalizer.rs index 9a5a2ee..34faa72 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -1055,6 +1055,12 @@ mod test { validator::IntrinsicValidator, }; + #[test] + fn test_sync() { + fn is_sync() {} + is_sync::(); + } + fn normalizers( mapper: &Mapper, ) -> Result<(Normalizer, Normalizer, Normalizer, Normalizer), Error> { From 0105fd143169eff3d7567d648b37826b63b93d5b Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 10:56:03 +0200 Subject: [PATCH 7/8] add hash --- src/static_data/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static_data/mod.rs b/src/static_data/mod.rs index 8c43d88..11b5282 100644 --- a/src/static_data/mod.rs +++ b/src/static_data/mod.rs @@ -10,7 +10,7 @@ const GRCH37_JSON_GZ: &[u8] = include_bytes!("_data/GRCh37.json.gz"); const GRCH37_P10_JSON_GZ: &[u8] = include_bytes!("_data/GRCh37.p10.json.gz"); const GRCH38_JSON_GZ: &[u8] = include_bytes!("_data/GRCh38.json.gz"); -#[derive(Debug, Deserialize, Enum, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Deserialize, Enum, Clone, Copy, PartialEq, Eq, Hash)] pub enum Assembly { Grch37, Grch37p10, From 5067ba6f51c6dd05f685f3d648ffae54e3b500fe Mon Sep 17 00:00:00 2001 From: Manuel Holtgrewe Date: Mon, 12 Jun 2023 11:17:50 +0200 Subject: [PATCH 8/8] bump hgvs version --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 375c5f0..f168510 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,8 +27,7 @@ postgres = { version = "0.19", features = ["with-chrono-0_4"] } quick_cache = "0.3" regex = "1.7" rustc-hash = "1.1" -#seqrepo = { version = "0.5" } -seqrepo = { git = "https://github.com/bihealth/seqrepo-rs.git", branch = "thread-safety" } +seqrepo = { version = "0.6" } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } thiserror = "1.0"