From 149d3a79bb62a22401f9da151e083b9faa467447 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Tue, 2 May 2023 10:31:36 +0200 Subject: [PATCH] Implement copy! for records --- CHANGELOG.md | 4 ++++ Project.toml | 2 +- src/fasta/record.jl | 10 ++++++++++ src/fastq/record.jl | 10 ++++++++++ test/fasta/record.jl | 24 +++++++++++++++++++----- test/fastq/record.jl | 29 ++++++++++++++++++++++------- 6 files changed, 66 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e2c60..b751020 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [2.1.0] +### Additions +* Implement `Base.copy!` for `FASTQRecord` and `FASTARecord` + ## [2.0.1] ### Bugfix * Fix `Base.read!(::FASTQReader, ::FASTQRecord)` (issue #95) diff --git a/Project.toml b/Project.toml index b947fbd..29aeec9 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "FASTX" uuid = "c2308a5c-f048-11e8-3e8a-31650f418d12" authors = ["Sabrina J. Ward ", "Jakob N. Nissen "] -version = "2.0.1" +version = "2.1.0" [weakdeps] BioSequences = "7e6ae17a-c86d-528c-b3b9-7f778a29fe59" diff --git a/src/fasta/record.jl b/src/fasta/record.jl index b53801c..c6d4208 100644 --- a/src/fasta/record.jl +++ b/src/fasta/record.jl @@ -122,6 +122,16 @@ function Base.copy(record::Record) ) end +function Base.copy!(dst::Record, src::Record) + n = filled(src) + length(dst.data) < n && resize!(dst.data, n) + unsafe_copyto!(dst.data, 1, src.data, 1, n) + dst.identifier_len = src.identifier_len + dst.description_len = src.description_len + dst.sequence_len = src.sequence_len + dst +end + function Base.write(io::IO, record::Record) data = record.data write(io, UInt8('>')) diff --git a/src/fastq/record.jl b/src/fastq/record.jl index 25377f5..1a4bb64 100644 --- a/src/fastq/record.jl +++ b/src/fastq/record.jl @@ -178,6 +178,16 @@ function Base.copy(record::Record) ) end +function Base.copy!(dst::Record, src::Record) + n = filled(src) + length(dst.data) < n && resize!(dst.data, n) + unsafe_copyto!(dst.data, 1, src.data, 1, n) + dst.identifier_len = src.identifier_len + dst.description_len = src.description_len + dst.has_description_seq_len = src.has_description_seq_len + dst +end + function Base.write(io::IO, record::Record) data = record.data len = UInt(seqsize(record)) diff --git a/test/fasta/record.jl b/test/fasta/record.jl index 9163914..fa13a02 100644 --- a/test/fasta/record.jl +++ b/test/fasta/record.jl @@ -10,11 +10,6 @@ empty!(record) @test record == record2 - # Copying - cp = copy(record) - @test record == cp - @test record.data !== cp.data - # Components of empty records @test identifier(record) isa AbstractString @test isempty(identifier(record)) @@ -129,6 +124,25 @@ end @test sequence(String, cp) == "OOJMQQ" end +@testset "Copying" begin + record = parse(Record, ">some_identifier \tmy_description | text\nAAT\nTA\nCCG") + resize!(record.data, 1000) + cp = copy(record) + + @test record !== cp + @test record == cp + @test sequence(record) == sequence(cp) + @test identifier(record) == identifier(cp) + @test description(record) == description(cp) + @test record.data !== cp.data + + record = parse(Record, ">another record\r\nUAGWMPK\nKKLLAAM") + @test record != cp + copy!(record, cp) + @test record !== cp + @test record == cp +end + # Get sequence as String/StringView @testset "Get sequence" begin record = Record(codeunits("ab cAACCAAGGTTKKKMMMM"), 2, 4, 10) diff --git a/test/fastq/record.jl b/test/fastq/record.jl index 533642c..97d64ed 100644 --- a/test/fastq/record.jl +++ b/test/fastq/record.jl @@ -10,13 +10,6 @@ empty!(record) @test record == record2 - # Copying - resize!(record.data, 1000) - cp = copy(record) - empty!(record.data) - @test record == cp - @test record.data !== cp.data - # Components of empty records @test identifier(record) == "" @test description(record) == "" @@ -122,6 +115,28 @@ end end end +@testset "Copying" begin + record = parse(Record, "@A\nTGGAA\n+\nJJJAA") + resize!(record.data, 1000) + cp = copy(record) + + @test record !== cp + @test record == cp + @test sequence(record) == sequence(cp) + @test identifier(record) == identifier(cp) + @test description(record) == description(cp) + @test quality(record) == quality(cp) + @test record.data !== cp.data + # Test that we don't unnecessarily copy noncoding data + @test length(record.data) > length(cp.data) + + record = parse(Record, "@some other record\r\nTAGA\r\n+\r\nJJJK") + @test record != cp + copy!(record, cp) + @test record !== cp + @test record == cp +end + @testset "Get sequence as String/StringView" begin records = map(i -> parse(Record, i), TEST_RECORD_STRINGS)