///|
fn parse_gff3_attributes(raw : String) -> Array[Attribute] {
let attrs : Array[Attribute] = []
for part_view in raw.split(";") {
let part = part_view.trim().to_owned()
if !part.is_empty() {
let pieces = part.split("=").to_array()
if pieces.length() >= 2 {
attrs.push({
key: pieces[0].trim().to_owned(),
value: percent_unescape(pieces[1].trim().to_owned()),
})
} else {
attrs.push({ key: part, value: "" })
}
}
}
attrs
}
///|
fn parse_gtf_attributes(raw : String) -> Array[Attribute] {
let attrs : Array[Attribute] = []
for part_view in raw.split(";") {
let part = part_view.trim().to_owned()
if !part.is_empty() {
let pieces = part.split(" ").to_array()
if pieces.length() >= 2 {
let key = pieces[0].trim().to_owned()
let value = trim_quotes(part[key.length():].trim().to_owned())
attrs.push({ key, value })
}
}
}
attrs
}
///|
fn trim_quotes(s : String) -> String {
if s.length() >= 2 && s[0] == '"' && s[s.length() - 1] == '"' {
s[1:s.length() - 1].to_owned()
} else {
s
}
}
///|
fn percent_unescape(s : String) -> String {
s
.replace(old="%20", new=" ")
.replace(old="%3B", new=";")
.replace(old="%3D", new="=")
}