From 9bda5f768a5c54767c7e08ef1cafd28ff3f2a3b3 Mon Sep 17 00:00:00 2001 From: Gert Hulselmans Date: Tue, 12 Nov 2024 15:59:34 +0100 Subject: [PATCH 1/7] fix: return error when bgzf_open fails to open a file (#444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Before `rust_htslib::bgzf:Reader` and `rust_htslib::bgzf:Writer` would never fail when opening a file that could not be opened and it would allow writing to `rust_htslib::bgzf:Writer` without returning any error messages. Co-authored-by: Johannes Köster --- src/bgzf/mod.rs | 16 ++++++++++++++-- src/errors.rs | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/bgzf/mod.rs b/src/bgzf/mod.rs index 06d6ee7a1..cc0a259fa 100644 --- a/src/bgzf/mod.rs +++ b/src/bgzf/mod.rs @@ -87,7 +87,13 @@ impl Reader { let mode = ffi::CString::new("r").unwrap(); let cpath = ffi::CString::new(path).unwrap(); let inner = unsafe { htslib::bgzf_open(cpath.as_ptr(), mode.as_ptr()) }; - Ok(Self { inner }) + if inner != std::ptr::null_mut() { + Ok(Self { inner }) + } else { + Err(Error::FileOpen { + path: String::from_utf8(path.to_vec()).unwrap(), + }) + } } /// Set the thread pool to use for parallel decompression. @@ -211,7 +217,13 @@ impl Writer { let mode = Self::get_open_mode(level)?; let cpath = ffi::CString::new(path).unwrap(); let inner = unsafe { htslib::bgzf_open(cpath.as_ptr(), mode.as_ptr()) }; - Ok(Self { inner, tpool: None }) + if inner != std::ptr::null_mut() { + Ok(Self { inner, tpool: None }) + } else { + Err(Error::FileOpen { + path: String::from_utf8(path.to_vec()).unwrap(), + }) + } } /// Internal function to convert compression level to "mode" diff --git a/src/errors.rs b/src/errors.rs index 2e89854f0..1fdc8f273 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -10,6 +10,8 @@ pub enum Error { // General errors #[error("file not found: {path}")] FileNotFound { path: PathBuf }, + #[error("file could not be opened: {path}")] + FileOpen { path: String }, #[error("invalid (non-unicode) characters in path")] NonUnicodePath, #[error("failed to fetch region")] From 489c0d7677445cfe38580c8d4c843ad4f4e2d827 Mon Sep 17 00:00:00 2001 From: Chris Saunders Date: Tue, 12 Nov 2024 07:00:37 -0800 Subject: [PATCH 2/7] feat: Add to_vcf_string method for bcf::Record (#443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add bcf record to_vcf_string method and test * Reformat as Display trait * Revert to Record::to_vcf_string method Added return value checking on vcf_format, which also suggests that the methods should return a Result and shound't be implemented directly as a Display trait. --------- Co-authored-by: Johannes Köster --- src/bcf/record.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++ src/errors.rs | 2 ++ 2 files changed, 60 insertions(+) diff --git a/src/bcf/record.rs b/src/bcf/record.rs index c1066cd30..e84a6273f 100644 --- a/src/bcf/record.rs +++ b/src/bcf/record.rs @@ -1088,6 +1088,38 @@ impl Record { } "".to_owned() } + + /// Convert to VCF String + /// + /// Intended for debug only. Use Writer for efficient VCF output. + /// + pub fn to_vcf_string(&self) -> Result { + let mut buf = htslib::kstring_t { + l: 0, + m: 0, + s: ptr::null_mut(), + }; + let ret = unsafe { htslib::vcf_format(self.header().inner, self.inner, &mut buf) }; + + if ret < 0 { + if !buf.s.is_null() { + unsafe { + libc::free(buf.s as *mut libc::c_void); + } + } + return Err(Error::BcfToString); + } + + let vcf_str = unsafe { + let vcf_str = String::from(ffi::CStr::from_ptr(buf.s).to_str().unwrap()); + if !buf.s.is_null() { + libc::free(buf.s as *mut libc::c_void); + } + vcf_str + }; + + Ok(vcf_str) + } } impl Clone for Record { @@ -1714,4 +1746,30 @@ mod tests { assert!(!record.has_filter(&bar)); assert!(record.has_filter("PASS".as_bytes())); } + + #[test] + fn test_record_to_vcf_string_err() { + let tmp = NamedTempFile::new().unwrap(); + let path = tmp.path(); + let header = Header::new(); + let vcf = Writer::from_path(path, &header, true, Format::Vcf).unwrap(); + let record = vcf.empty_record(); + assert!(record.to_vcf_string().is_err()); + } + + #[test] + fn test_record_to_vcf_string() { + let tmp = NamedTempFile::new().unwrap(); + let path = tmp.path(); + let mut header = Header::new(); + header.push_record(b"##contig="); + header.push_record(br#"##FILTER="#); + let vcf = Writer::from_path(path, &header, true, Format::Vcf).unwrap(); + let mut record = vcf.empty_record(); + record.push_filter("foo".as_bytes()).unwrap(); + assert_eq!( + record.to_vcf_string().unwrap(), + "chr1\t1\t.\t.\t.\t0\tfoo\t.\n" + ); + } } diff --git a/src/errors.rs b/src/errors.rs index 1fdc8f273..a8c32e585 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -131,6 +131,8 @@ pub enum Error { BcfSetValues, #[error("failed to remove alleles in BCF/VCF record")] BcfRemoveAlleles, + #[error("failed to render BCF record as string")] + BcfToString, #[error("invalid compression level {level}")] BgzfInvalidCompressionLevel { level: i8 }, From 2e6ea493081c9e44f3181b8e358bd52d8cb699e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20K=C3=B6ster?= Date: Tue, 12 Nov 2024 16:01:41 +0100 Subject: [PATCH 3/7] Update dependabot.yml --- .github/dependabot.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 32e25341c..53f8242a9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,7 +4,3 @@ updates: directory: "/" schedule: interval: "weekly" - commit-message: - # Prefix all commit messages with "deps: ", which should be - # accepted as a conventional commit and trigger release-please - prefix: "deps" From 4e472d72f9ea15e54d8cc90ff92cc8d05cb19176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:02:31 +0100 Subject: [PATCH 4/7] deps: update derive-new requirement from 0.5 to 0.7 (#450) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the requirements on [derive-new](https://github.com/nrc/derive-new) to permit the latest version. - [Commits](https://github.com/nrc/derive-new/compare/0.5.1...0.7) --- updated-dependencies: - dependency-name: derive-new dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Felix Mölder --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bbfe8cc80..82c8f5db2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ libz-sys = ">=1.1.15" bio-types = ">=0.9" byteorder = "1.3" custom_derive = "0.1" -derive-new = "0.5" +derive-new = "0.7" hts-sys = {version = "2.1.4", default-features = false, features = ["bindgen"]} ieee754 = "0.2" lazy_static = "1.4" From 37b2e4458d5c2cf395a2300ef825f0df484d49ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:02:43 +0100 Subject: [PATCH 5/7] deps: update pretty_assertions requirement from 0.6 to 1.4 (#449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the requirements on [pretty_assertions](https://github.com/rust-pretty-assertions/rust-pretty-assertions) to permit the latest version. - [Release notes](https://github.com/rust-pretty-assertions/rust-pretty-assertions/releases) - [Changelog](https://github.com/rust-pretty-assertions/rust-pretty-assertions/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-pretty-assertions/rust-pretty-assertions/compare/v0.6.0...v1.4.1) --- updated-dependencies: - dependency-name: pretty_assertions dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Felix Mölder --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 82c8f5db2..41d27bb96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,6 @@ static = ["hts-sys/static"] [dev-dependencies] bincode = "1.2" -pretty_assertions = "0.6" +pretty_assertions = "1.4" serde_json = "1.0" tempfile = "3.1.0" From 579b11ad330e0e33510868df7ab969389b9ce767 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:02:53 +0100 Subject: [PATCH 6/7] deps: update thiserror requirement from 1 to 2 (#448) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the requirements on [thiserror](https://github.com/dtolnay/thiserror) to permit the latest version. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.0...2.0.3) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Felix Mölder --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 41d27bb96..c9d2dc323 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ newtype_derive = "0.1" regex = "1.3" serde = {version = "^1", optional = true, features = ["derive"]} serde_bytes = {version = "0.11", optional = true} -thiserror = "1" +thiserror = "2" url = "2.1" [features] From 7f3cfea8f084a479f4e71680e744bb8252d1b68c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:04:24 +0100 Subject: [PATCH 7/7] chore(master): release 0.48.0 (#452) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- CHANGELOG.md | 12 ++++++++++++ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79337f4b9..76a36e849 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.48.0](https://github.com/rust-bio/rust-htslib/compare/v0.47.1...v0.48.0) (2024-11-12) + + +### Features + +* Add to_vcf_string method for bcf::Record ([#443](https://github.com/rust-bio/rust-htslib/issues/443)) ([489c0d7](https://github.com/rust-bio/rust-htslib/commit/489c0d7677445cfe38580c8d4c843ad4f4e2d827)) + + +### Bug Fixes + +* return error when bgzf_open fails to open a file ([#444](https://github.com/rust-bio/rust-htslib/issues/444)) ([9bda5f7](https://github.com/rust-bio/rust-htslib/commit/9bda5f768a5c54767c7e08ef1cafd28ff3f2a3b3)) + ## [0.47.1](https://github.com/rust-bio/rust-htslib/compare/v0.47.0...v0.47.1) (2024-11-12) diff --git a/Cargo.toml b/Cargo.toml index c9d2dc323..d1428a77d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT" name = "rust-htslib" readme = "README.md" repository = "https://github.com/rust-bio/rust-htslib.git" -version = "0.47.1" +version = "0.48.0" [package.metadata.release] pre-release-commit-message = "release version {{version}}"