diff --git a/.github/workflow/rust.yml b/.github/workflow/rust.yml new file mode 100644 index 0000000..152107a --- /dev/null +++ b/.github/workflow/rust.yml @@ -0,0 +1,112 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + Formatting: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + components: rustfmt + + - name: Check format + run: cargo fmt -- --check + + Linting: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + components: clippy + + - name: Lint with clippy + uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + Testing: + needs: Formatting + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + build: [beta, stable, windows, macos] + include: + - build: macos + os: macos-latest + rust: stable + - build: windows + os: windows-latest + rust: stable + - build: beta + os: ubuntu-latest + rust: beta + - build: stable + os: ubuntu-latest + rust: stable + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + + - name: Install ${{ matrix.rust }} toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + + - name: Run tests + uses: actions-rs/cargo@v1 + with: + command: test + args: --all --no-fail-fast + + Coverage: + needs: Formatting + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install nightly toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + + - name: Install cargo-tarpaulin + uses: actions-rs/install@v0.1 + with: + crate: cargo-tarpaulin + version: latest + use-tool-cache: true + + - name: Coverage with tarpaulin + run: cargo tarpaulin --all --all-features --timeout 600 --out Lcov -- --test-threads 1 + + - name: Upload coverage + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ./lcov.info \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c2bdb42..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: rust - -rust: - - stable - -cache: cargo - -sudo: false - -# Dependencies of kcov, used for cargo-travis -addons: - apt: - packages: - - libcurl4-openssl-dev - - libelf-dev - - libdw-dev - - binutils-dev - - cmake - sources: - - kalakris-cmake - -before_script: - - cargo install --force cargo-travis - - export PATH=$HOME/.cargo/bin:$PATH - - rustup component add rustfmt-preview - -script: - - cargo fmt --all -- --check - - cargo build - - cargo test - -after_success: - - cargo coveralls - -env: - global: - - RUST_BACKTRACE=1 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..22bf06e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Change Log +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + +## [next] +- BREAKING: Adding serialization with `serde` as a feature: `serde_feature`. +- Adding `Debug` and `Serialize`/`Deserialize` traits to a couple of more types. +- Moving from Travis CI to Github Actions for CI. + +## [0.7.0] - 2020-07-02 +No changelog is kept up to and including this version. diff --git a/Cargo.toml b/Cargo.toml index 8128f31..0d9d077 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,16 @@ homepage = "https://rust-bio.github.io" repository = "https://github.com/rust-bio/rust-bio" documentation = "https://docs.rs/bio" readme = "README.md" -license = "MIT" license-file = "LICENSE.md" +[features] +serde_feature = ["serde", "serde_derive"] [dependencies] -serde = "1.0" -serde_derive = "1.0" quick-error = "1.2" regex = "1.0" lazy_static = "1.1" derive-new = "0.5" + +serde = { version = "1.0", optional = true } +serde_derive = { version = "1.0", optional = true } diff --git a/src/alignment.rs b/src/alignment.rs index 7284694..17971c3 100644 --- a/src/alignment.rs +++ b/src/alignment.rs @@ -15,7 +15,8 @@ pub type TextSlice<'a> = &'a [u8]; /// value associated with the clipping operations are the lengths clipped. In case /// of standard modes like Global, Semi-Global and Local alignment, the clip operations /// are filtered out -#[derive(Eq, PartialEq, Debug, Copy, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(Eq, PartialEq, Debug, Copy, Clone)] pub enum AlignmentOperation { Match, Subst, @@ -33,7 +34,8 @@ pub enum AlignmentOperation { /// appropriately set. /// /// The default alignment mode is Global. -#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum AlignmentMode { Local, Semiglobal, @@ -53,7 +55,8 @@ impl Default for AlignmentMode { /// lengths of sequences x and y, and the alignment edit operations. The start position /// and end position of the alignment does not include the clipped regions. The length /// of clipped regions are already encapsulated in the Alignment Operation. -#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Default)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(Debug, Eq, PartialEq, Clone, Default)] pub struct Alignment { /// Smith-Waterman alignment score pub score: i32, diff --git a/src/annot/contig.rs b/src/annot/contig.rs index 136c439..8cc998b 100644 --- a/src/annot/contig.rs +++ b/src/annot/contig.rs @@ -43,6 +43,7 @@ use strand::*; /// # } /// # fn main() { try_main().unwrap(); } /// ``` +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Contig { refid: R, diff --git a/src/annot/mod.rs b/src/annot/mod.rs index b96dd49..63ac55a 100644 --- a/src/annot/mod.rs +++ b/src/annot/mod.rs @@ -54,6 +54,7 @@ pub mod spliced; // Errors that arise in parsing annotations. quick_error! { + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone)] pub enum ParseAnnotError { BadAnnot { @@ -76,6 +77,7 @@ quick_error! { // Errors that arise in maniuplating annotations quick_error! { + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone)] pub enum AnnotError { NoStrand { diff --git a/src/annot/pos.rs b/src/annot/pos.rs index 92d5ca1..9fff06c 100644 --- a/src/annot/pos.rs +++ b/src/annot/pos.rs @@ -42,6 +42,7 @@ use strand::*; /// # } /// # fn main() { try_main().unwrap(); } /// ``` +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Pos { refid: R, diff --git a/src/annot/refids.rs b/src/annot/refids.rs index d0b4461..e29a5db 100644 --- a/src/annot/refids.rs +++ b/src/annot/refids.rs @@ -37,6 +37,8 @@ use std::ops::Deref; /// assert_eq!(Rc::strong_count(&chr_i), 7); /// } /// ``` +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(Debug)] pub struct RefIDSet { refids: HashMap, } diff --git a/src/annot/spliced.rs b/src/annot/spliced.rs index edf93c6..ffd82f6 100644 --- a/src/annot/spliced.rs +++ b/src/annot/spliced.rs @@ -37,6 +37,7 @@ mod inex { use super::SplicingError; + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InEx { intron_length: usize, @@ -69,6 +70,7 @@ mod inex { // Represent just the start (relative to the start of the location) and length of exons // Useful for internal coordinate math + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Ex { start: usize, @@ -88,12 +90,15 @@ mod inex { } // Iterator over the Ex exons from lowest to highest coordinate + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] + #[derive(Debug)] pub struct Exes<'a> { state: ExesState, curr_start: usize, rest: Iter<'a, InEx>, } + #[derive(Debug)] enum ExesState { FirstExon(usize), LaterExon, @@ -140,6 +145,7 @@ mod inex { // Represent just the start (relative to the start of the location) and length of introns // Useful for internal coordinate math + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct In { start: usize, @@ -160,6 +166,8 @@ mod inex { } // Iterator over the Ex introns from lowest to highest coordinate + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] + #[derive(Debug)] pub struct Ins<'a> { curr_start: usize, rest: Iter<'a, InEx>, @@ -223,6 +231,7 @@ mod inex { /// # } /// # fn main() { try_main().unwrap(); } /// ``` +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Spliced { refid: R, @@ -687,6 +696,7 @@ pub type SeqSplicedStranded = Spliced; pub type SeqSplicedUnstranded = Spliced; quick_error! { + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone)] pub enum SplicingError { IntronLength { diff --git a/src/genome.rs b/src/genome.rs index d28fd15..0f79a99 100644 --- a/src/genome.rs +++ b/src/genome.rs @@ -20,7 +20,8 @@ pub trait AbstractInterval { } } -#[derive(new, Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(new, Debug, PartialEq, Eq, Clone, Hash)] pub struct Interval { contig: String, range: Range, @@ -67,7 +68,8 @@ pub trait AbstractLocus { fn pos(&self) -> Position; } -#[derive(new, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(new, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] pub struct Locus { contig: String, pos: Position, diff --git a/src/lib.rs b/src/lib.rs index 8396bec..902afef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ -#[macro_use] +#[cfg_attr(feature = "serde_feature", macro_use)] +#[cfg(feature = "serde_feature")] extern crate serde_derive; #[macro_use] extern crate quick_error; diff --git a/src/strand.rs b/src/strand.rs index bd9b195..fab1865 100644 --- a/src/strand.rs +++ b/src/strand.rs @@ -10,6 +10,7 @@ use std::ops::Neg; use std::str::FromStr; /// Strand information. +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Copy)] pub enum Strand { Forward, @@ -134,6 +135,7 @@ impl From for Strand { } /// Strand information for annotations that require a strand. +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd, Copy)] pub enum ReqStrand { Forward, @@ -243,6 +245,7 @@ impl Neg for ReqStrand { /// Strand information for annotations that definitively have no /// strand information. +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd, Copy)] pub enum NoStrand { Unknown, @@ -302,6 +305,7 @@ where } quick_error! { + #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[derive(Debug, Clone)] pub enum StrandError { InvalidChar(invalid_char: char) { diff --git a/src/variant.rs b/src/variant.rs index 4bc7ad9..89155df 100644 --- a/src/variant.rs +++ b/src/variant.rs @@ -7,7 +7,8 @@ pub trait AbstractVariant: genome::AbstractLocus { } /// Possible genomic variants. -#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq, Eq, Clone, Hash)] pub enum Kind { SNV(Base), MNV(Sequence),