use crate::general::{Date, DbTag, IntFuzz, ObjectId, UserObject};
use crate::parsing::{read_vec_node, read_attributes, read_int, read_node, read_string, UnexpectedTags, attribute_value};
use crate::r#pub::PubEquiv;
use crate::seqalign::SeqAlign;
use crate::seqblock::{EMBLBlock, GBBlock, PDBBlock, PIRBlock, PRFBlock, SPBlock};
use crate::seqfeat::{BioSource, ModelEvidenceSupport, OrgRef, SeqFeat};
use crate::seqloc::{SeqId, SeqLoc};
use crate::seqres::SeqGraph;
use crate::seqtable::SeqTable;
use crate::parsing::{XmlNode, XmlVecNode, XmlValue};
use enum_primitive::FromPrimitive;
use quick_xml::events::{BytesStart, Event};
use quick_xml::events::attributes::Attributes;
use quick_xml::Reader;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub struct BioSeq {
pub id: Vec<SeqId>,
pub descr: Option<SeqDescr>,
pub inst: Option<SeqInst>, pub annot: Option<Vec<SeqAnnot>>,
}
impl XmlNode for BioSeq {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Bioseq")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> {
let mut bioseq = Self::default();
let id_elem = BytesStart::new("Bioseq_id");
let descr_elem = BytesStart::new("Bioseq_descr");
let inst_elem = BytesStart::new("Bioseq_inst");
let annot_elem = BytesStart::new("Bioseq_annot");
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == id_elem.name() {
bioseq.id = read_vec_node(reader, id_elem.to_end());
} else if name == descr_elem.name() {
bioseq.descr = read_node(reader);
} else if name == inst_elem.name() {
bioseq.inst = read_node(reader);
} else if name == annot_elem.name() {
bioseq.annot = Some(read_vec_node(reader, annot_elem.to_end()));
}
}
Event::End(e) => {
if Self::is_end(&e) {
return bioseq.into();
}
}
_ => (),
}
}
}
}
pub type SeqDescr = Vec<SeqDesc>;
impl XmlNode for SeqDescr {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-descr")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> {
return SeqDesc::vec_from_reader(reader, Self::start_bytes().to_end()).into();
}
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum SeqDesc {
#[deprecated]
MolType(GIBBMol),
#[deprecated]
Modif(GIBBMod),
#[deprecated]
Method(GIBBMethod),
Name(String),
Title(String),
#[deprecated]
Org(OrgRef),
Comment(String),
Num(Numbering),
MapLoc(DbTag),
PIR(PIRBlock),
Genbank(GBBlock),
Pub(PubDesc),
Region(String),
User(UserObject),
SP(SPBlock),
DbXref(DbTag),
Embl(EMBLBlock),
CreateDate(Date),
UpdateDate(Date),
PRF(PRFBlock),
PDB(PDBBlock),
Het(Heterogen),
Source(BioSource),
MolInfo(MolInfo),
ModelEv(ModelEvidenceSupport),
}
impl XmlNode for SeqDesc {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seqdesc")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> {
let source_element = BytesStart::new("Seqdesc_source");
let molinfo_element = BytesStart::new("Seqdesc_molinfo");
let pub_element = BytesStart::new("Seqdesc_pub");
let comment_element = BytesStart::new("Seqdesc_comment");
let user_element = BytesStart::new("Seqdesc_user");
let create_element = BytesStart::new("Seqdesc_create-date");
let update_element = BytesStart::new("Seqdesc_update-date");
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == source_element.name() {
return Self::Source(read_node(reader).unwrap()).into();
} else if name == molinfo_element.name() {
return Self::MolInfo(read_node(reader).unwrap()).into();
} else if name == pub_element.name() {
return Self::Pub(read_node(reader).unwrap()).into();
} else if name == comment_element.name() {
return Self::Comment(read_string(reader).unwrap()).into();
} else if name == user_element.name() {
return Self::User(read_node(reader).unwrap()).into();
} else if name == create_element.name() {
return Self::CreateDate(read_node(reader).unwrap()).into()
} else if name == update_element.name() {
return Self::UpdateDate(read_node(reader).unwrap()).into()
}
}
Event::End(e) => {
if Self::is_end(&e) {
return None;
}
}
_ => (),
}
}
}
}
impl XmlVecNode for SeqDesc {}
enum_from_primitive! {
#[allow(non_camel_case_types)]
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug, Default)]
#[repr(u8)]
pub enum BioMol {
#[default]
Unknown,
Genomic,
PreRNA,
mRNA,
rRNA,
tRNA,
snRNA,
scRNA,
Peptide,
OtherGenetic,
Genomic_mRNA,
cRNA,
snoRNA,
TranscribedRNA,
ncRNA,
tmRNA,
Other = 255,
}
}
impl XmlNode for BioMol {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("MolInfo_biomol")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self>
where
Self: Sized,
{
BioMol::from_u8(read_int::<u8>(reader).unwrap())
}
}
enum_from_primitive! {
#[allow(non_camel_case_types)]
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug, Default)]
#[repr(u8)]
pub enum MolTech {
#[default]
Unknown,
Standard,
EST,
STS,
Survey,
GeneMap,
PhysMap,
Derived,
ConceptTrans,
SeqPept,
Both,
SeqPeptOverlap,
SeqPeptHomol,
ConceptTransA,
HTGS1,
HTGS2,
HTGS3,
FLI_cDNA,
HTGS0,
HTC,
WGS,
Barcode,
CompositeWgsHtgs,
TSA,
Targeted,
Other = 255,
}
}
impl XmlNode for MolTech {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("MolInfo_tech")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self>
where
Self: Sized,
{
MolTech::from_u8(read_int::<u8>(reader).unwrap())
}
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug, Default)]
#[repr(u8)]
pub enum MolCompleteness {
#[default]
Unknown,
Complete,
Partial,
NoLeft,
NoRight,
NoEnds,
HasLeft,
HasRight,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub struct MolInfo {
pub bio_mol: BioMol,
pub tech: MolTech,
pub tech_exp: Option<String>,
pub completeness: MolCompleteness,
pub gb_mol_type: Option<String>,
}
impl XmlNode for MolInfo {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("MolInfo")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self>
where
Self: Sized,
{
let mut mol_info = Self::default();
let bio_mol_element = BytesStart::new("MolInfo_biomol");
let tech_element = BytesStart::new("MolInfo_tech");
let forbidden = UnexpectedTags(&[]);
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == bio_mol_element.name() {
mol_info.bio_mol = read_node(reader).unwrap();
} else if name == tech_element.name() {
mol_info.tech = read_node(reader).unwrap();
} else if name != Self::start_bytes().name() {
forbidden.check(&name);
}
}
Event::End(e) => {
if Self::is_end(&e) {
return mol_info.into();
}
}
_ => (),
}
}
}
}
#[allow(non_camel_case_types)]
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum GIBBMol {
Unknown,
Genomic,
PreRNA,
mRNA,
rRNA,
tRNA,
snRNA,
scRNA,
Peptide,
OtherGenetic,
Genomic_mRNA,
Other = 255,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum GIBBMod {
DNA,
RNA,
ExtraChrom,
Plasmid,
Mitochondrial,
Chloroplast,
Kinetoplast,
Cyanelle,
Synthetic,
Recombinant,
Partial,
Complete,
Mutagen,
NatMut,
Transposon,
InsertionSeq,
NoLeft,
NoRight,
MacroNuclear,
ProViral,
EST,
STS,
Survey,
Chromoplast,
GeneMap,
RestMap,
PhysMap,
Other = 255,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum GIBBMethod {
ConceptTrans = 1,
SeqPept,
Both,
SeqPeptOverlap,
SeqPeptHomol,
ConceptTransA,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum Numbering {
Cont(NumCont),
Enum(NumEnum),
Ref(NumRef),
Real(NumReal),
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub struct NumCont {
pub ref_num: u64,
pub has_zero: bool,
pub ascending: bool,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct NumEnum {
pub num: u64,
pub names: Vec<String>,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum NumRefType {
NotSet,
Sources,
Aligns,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct NumRef {
pub r#type: NumRefType,
pub aligns: Option<SeqAlign>,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct NumReal {
pub a: f64,
pub b: f64,
pub units: Option<String>,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub enum PubDescRefType {
#[default]
Seq,
Sites,
Feats,
NoTarget,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug, Default)]
#[serde(rename_all = "kebab-case")]
pub struct PubDesc {
pub r#pub: PubEquiv,
pub name: Option<String>,
pub fig: Option<String>,
pub num: Option<Numbering>,
pub num_exc: Option<bool>,
pub poly_a: Option<bool>,
pub map_loc: Option<String>,
pub seq_raw: Option<String>,
pub align_group: Option<i64>,
pub comment: Option<String>,
pub ref_type: PubDescRefType,
}
impl XmlNode for PubDesc {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Pubdesc")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self>
where
Self: Sized,
{
let mut desc = Self::default();
let pub_element = BytesStart::new("Pubdesc_pub");
let forbidden = UnexpectedTags(&[]);
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == pub_element.name() {
desc.r#pub = read_node(reader).unwrap();
} else if name != Self::start_bytes().name() {
forbidden.check(&name);
}
}
Event::End(e) => {
if Self::is_end(&e) {
return desc.into();
}
}
_ => (),
}
}
}
}
pub type Heterogen = String;
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum Repr {
NotSet,
Virtual,
Raw,
Seg,
Const,
Ref,
Consen,
Map,
Delta,
Other = 255,
}
impl XmlValue for Repr {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-inst_repr")
}
fn from_attributes(attributes: Attributes) -> Option<Self> {
if let Some(attributes) = attribute_value(attributes) {
match attributes.as_str() {
"not-set" => Self::NotSet.into(),
"virtual" => Self::Virtual.into(),
"raw" => Self::Raw.into(),
"seg" => Self::Seg.into(),
"const" => Self::Const.into(),
"ref" => Self::Ref.into(),
"consen" => Self::Consen.into(),
"map" => Self::Map.into(),
"delta" => Self::Delta.into(),
"other" => Self::Other.into(),
_ => None
}
} else {
None
}
}
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum Mol {
NotSet,
DNA,
RNA,
AA,
NA,
Other = 255,
}
impl XmlValue for Mol {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-inst_mol")
}
fn from_attributes(attributes: Attributes) -> Option<Self> {
if let Some(attributes) = attribute_value(attributes) {
match attributes.as_str() {
"not-set" => Self::NotSet.into(),
"dna" => Self::DNA.into(),
"rna" => Self::NotSet.into(),
"aa" => Self::DNA.into(),
"na" => Self::DNA.into(),
"other" => Self::Other.into(),
_ => None
}
} else {
None
}
}
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug, Default)]
#[repr(u8)]
pub enum Topology {
NotSet,
#[default]
Linear,
Circular,
Tandem,
Other = 255,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum Strand {
NotSet,
SS,
DS,
Mixed,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct SeqInst {
pub repr: Repr,
pub mol: Mol,
pub length: Option<u64>,
pub fuzz: Option<IntFuzz>,
pub topology: Topology,
pub strand: Strand,
pub seq_data: Option<SeqData>,
pub ext: Option<SeqExt>,
pub hist: Option<SeqHist>,
}
impl Default for SeqInst {
fn default() -> Self {
let repr = Repr::Other;
let mol = Mol::Other;
let strand = Strand::NotSet;
Self {
repr, mol,
length: None,
fuzz: None,
topology: Default::default(),
strand,
seq_data: None,
ext: None,
hist: None,
}
}
}
impl XmlNode for SeqInst {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-inst")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> where Self: Sized {
let mut inst = Self::default();
let repr_element = BytesStart::new("Seq-inst_repr");
let mol_element = BytesStart::new("Seq-inst_mol");
let length_element = BytesStart::new("Seq-inst_length");
let ext_element = BytesStart::new("Seq-inst_ext");
let forbidden = UnexpectedTags(&[]);
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == length_element.name() {
inst.length = read_int(reader);
} else if name == ext_element.name() {
inst.ext = read_node(reader);
} else if name != Self::start_bytes().name() {
forbidden.check(&name);
}
}
Event::Empty(e) => {
let name = e.name();
if name == repr_element.name() {
inst.repr = read_attributes(&e).unwrap();
} else if name == mol_element.name() {
inst.mol = read_attributes(&e).unwrap();
} else if name != Self::start_bytes().name() {
forbidden.check(&name);
}
}
Event::End(e) => {
if Self::is_end(&e) {
return inst.into()
}
}
_ => ()
}
}
}
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum SeqExt {
Seg(SegExt),
Ref(RefExt),
Map(MapExt),
Delta(DeltaExt),
}
impl XmlNode for SeqExt {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-ext")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> where Self: Sized {
let _seg_element = BytesStart::new("Seq-ext_seg");
let _ref_element = BytesStart::new("Seq-ext_ref");
let _map_element = BytesStart::new("Seq-ext_map");
let delta_element = BytesStart::new("Seq-ext_delta");
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == delta_element.name() {
return Self::Delta(read_vec_node(reader, delta_element.to_end())).into();
}
}
Event::End(e) => {
if Self::is_end(&e) {
return None
}
},
_ => ()
}
}
}
}
pub type SegExt = Vec<SeqLoc>;
pub type RefExt = SeqLoc;
pub type MapExt = Vec<SeqFeat>;
pub type DeltaExt = Vec<DeltaSeq>;
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum DeltaSeq {
Loc(SeqLoc),
Literal(SeqLiteral),
}
impl XmlNode for DeltaSeq {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Delta-seq")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> where Self: Sized {
let loc_variant = BytesStart::new("Delta-seq_loc");
let _literal_variant = BytesStart::new("Delta-seq_literal");
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == loc_variant.name() {
return Self::Loc(read_node(reader).unwrap()).into()
}
}
Event::End(e) => {
if Self::is_end(&e) {
return None
}
}
_ => ()
}
}
}
}
impl XmlVecNode for DeltaSeq {}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct SeqLiteral {
pub length: u64,
pub full: Option<IntFuzz>,
pub seq_data: Option<SeqData>,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum SeqHistDeleted {
Bool(bool),
Date(Date),
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct SeqHist {
pub assembly: Option<Vec<SeqAlign>>,
pub replaces: Option<SeqHistRec>,
pub replaced_by: Option<SeqHistRec>,
pub deleted: Option<SeqHistDeleted>,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct SeqHistRec {
pub date: Option<Date>,
pub ids: Vec<SeqId>,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum SeqData {
Ina(IUPACna),
Iaa(IUPACaa),
N2na(NCBI2na),
N4na(NCBI4na),
N8na(NCBI8na),
NPna(NCBIPna),
N8aa(NCBI8aa),
NEaa(NCBIEaa),
NPaa(NCBIPaa),
NStdAAs(NCBIStdAa),
Gap(SeqGap),
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum SeqGapType {
Unknown,
#[deprecated]
Fragment,
#[deprecated]
Clone,
ShortArm,
Heterochromatin,
Centromere,
Telomere,
Repeat,
Contig,
Scaffold,
Contamination,
Other = 255,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum SeqGapLinkage {
Unlinked,
Linked,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct SeqGap {
pub r#type: SeqGapType,
pub linkage: Option<SeqGapLinkage>,
pub linkage_evidence: Option<Vec<LinkageEvidence>>,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum LinkageEvidenceType {
PairedEnds,
AlignGenus,
AlignXGenus,
AlignTrans,
WithinClone,
CloneContig,
Map,
Strobe,
Unspecified,
PCR,
ProximityLigation,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct LinkageEvidence {
pub r#type: LinkageEvidenceType,
}
pub type IUPACna = String;
pub type IUPACaa = String;
pub type NCBI2na = Vec<u8>;
pub type NCBI4na = Vec<u8>;
pub type NCBI8na = Vec<u8>;
pub type NCBIPna = Vec<u8>;
pub type NCBI8aa = Vec<u8>;
pub type NCBIEaa = String;
pub type NCBIPaa = Vec<u8>;
pub type NCBIStdAa = Vec<u8>;
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct TextAnnotId {
pub name: Option<String>,
pub accession: Option<String>,
pub release: Option<String>,
pub version: Option<u64>,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum AnnotId {
Local(ObjectId),
NCBI(u64),
General(DbTag),
Other(TextAnnotId),
}
pub type AnnotDescr = Vec<AnnotDesc>;
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum AnnotDesc {
Name(String),
Title(String),
Comment(String),
Pub(PubDesc),
User(UserObject),
CreateDate(Date),
UpdateDate(Date),
Src(SeqId),
Align(AlignDef),
Region(SeqLoc),
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum AlignType {
Ref,
Alt,
Blocks,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct AlignDef {
pub align_type: AlignType,
pub ids: Option<Vec<SeqId>>,
}
#[derive(Clone, Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum SeqAnnotDB {
GenBank,
EMBL,
DDBJ,
PIR,
SP,
BBone,
PDB,
Other = 255,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "lowercase")]
pub enum SeqAnnotData {
FTable(Vec<SeqFeat>),
Align(Vec<SeqAlign>),
Graph(Vec<SeqGraph>),
IDS(Vec<SeqId>),
Locs(Vec<SeqLoc>),
#[serde(rename = "seq-table")]
SeqTable(SeqTable),
}
impl XmlNode for SeqAnnotData {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-annot_data")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> where Self: Sized {
let ftable_tag = BytesStart::new("Seq-annot_data_ftable");
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == ftable_tag.name() {
return Self::FTable(read_vec_node(reader, ftable_tag.to_end())).into()
}
}
Event::End(e) => {
if Self::is_end(&e) {
return None
}
}
_ => ()
}
}
}
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct SeqAnnot {
pub id: Option<Vec<AnnotId>>,
pub db: Option<SeqAnnotDB>,
pub name: Option<String>,
pub desc: Option<AnnotDescr>,
pub data: SeqAnnotData,
}
impl SeqAnnot {
pub fn default() -> Self {
Self::new(SeqAnnotData::FTable(vec![]))
}
pub fn new(data: SeqAnnotData) -> Self {
Self {
id: None,
db: None,
name: None,
desc: None,
data,
}
}
}
impl XmlNode for SeqAnnot {
fn start_bytes() -> BytesStart<'static> {
BytesStart::new("Seq-annot")
}
fn from_reader(reader: &mut Reader<&[u8]>) -> Option<Self> where Self: Sized {
let mut annot = SeqAnnot::default();
let data_tag = BytesStart::new("Seq-annot_data");
let forbidden = UnexpectedTags(&[]);
loop {
match reader.read_event().unwrap() {
Event::Start(e) => {
let name = e.name();
if name == data_tag.name() {
annot.data = read_node(reader).unwrap();
} else if name != Self::start_bytes().name() {
forbidden.check(&name);
}
}
Event::End(e) => {
if Self::is_end(&e) {
return annot.into()
}
}
_ => ()
}
}
}
}
impl XmlVecNode for SeqAnnot {}