1use std::io;
2
3use bigtools::bed::autosql::parse::Field as AutosqlField;
4use bigtools::bed::autosql::parse::FieldType as AutosqlType;
5
6pub use crate::bed::model::field_def::{
8 bed_standard_fields, FieldBuilder, FieldDef, FieldType, Push,
9};
10
11impl TryFrom<&AutosqlField> for FieldDef {
13 type Error = io::Error;
14
15 fn try_from(field: &AutosqlField) -> Result<Self, Self::Error> {
16 let ty = FieldType::try_from(field)?;
17 Ok(Self {
18 name: field.name.clone(),
19 ty,
20 })
21 }
22}
23
24impl TryFrom<&AutosqlField> for FieldType {
26 type Error = io::Error;
27
28 fn try_from(f: &AutosqlField) -> Result<Self, Self::Error> {
29 let ty = match &f.field_type {
30 AutosqlType::Byte => match &f.field_size {
31 None => Self::Byte,
32 Some(size_str) => match size_str.parse::<usize>() {
33 Ok(size) => Self::ByteFixedSizeList(size),
34 Err(_) => Self::ByteList,
35 },
36 },
37 AutosqlType::Ubyte => match &f.field_size {
38 None => Self::Ubyte,
39 Some(size_str) => match size_str.parse::<usize>() {
40 Ok(size) => Self::UbyteFixedSizeList(size),
41 Err(_) => Self::UbyteList,
42 },
43 },
44 AutosqlType::Short => match &f.field_size {
45 None => Self::Short,
46 Some(size_str) => match size_str.parse::<usize>() {
47 Ok(size) => Self::ShortFixedSizeList(size),
48 Err(_) => Self::ShortList,
49 },
50 },
51 AutosqlType::Ushort => match &f.field_size {
52 None => Self::Ushort,
53 Some(size_str) => match size_str.parse::<usize>() {
54 Ok(size) => Self::UshortFixedSizeList(size),
55 Err(_) => Self::UshortList,
56 },
57 },
58 AutosqlType::Int => match &f.field_size {
59 None => Self::Int,
60 Some(size_str) => match size_str.parse::<usize>() {
61 Ok(size) => Self::IntFixedSizeList(size),
62 Err(_) => Self::IntList,
63 },
64 },
65 AutosqlType::Uint => match &f.field_size {
66 None => Self::Uint,
67 Some(size_str) => match size_str.parse::<usize>() {
68 Ok(size) => Self::UintFixedSizeList(size),
69 Err(_) => Self::UintList,
70 },
71 },
72 AutosqlType::Bigint => match &f.field_size {
73 None => Self::Bigint,
74 Some(size_str) => match size_str.parse::<usize>() {
75 Ok(size) => Self::BigintFixedSizeList(size),
76 Err(_) => Self::BigintList,
77 },
78 },
79 AutosqlType::Float => match &f.field_size {
80 None => Self::Float,
81 Some(size_str) => match size_str.parse::<usize>() {
82 Ok(size) => Self::FloatFixedSizeList(size),
83 Err(_) => Self::FloatList,
84 },
85 },
86 AutosqlType::Double => match &f.field_size {
87 None => Self::Double,
88 Some(size_str) => match size_str.parse::<usize>() {
89 Ok(size) => Self::DoubleFixedSizeList(size),
90 Err(_) => Self::DoubleList,
91 },
92 },
93 AutosqlType::Char => Self::Char,
94 AutosqlType::String => Self::String,
95 AutosqlType::Lstring => Self::Lstring,
96 AutosqlType::Enum(items) => Self::Enum(items.clone()),
97 AutosqlType::Set(items) => Self::Set(items.clone()),
98 AutosqlType::Declaration(_, _) => {
99 return Err(io::Error::new(
100 io::ErrorKind::InvalidInput,
101 "Unsupported AutoSql type: Declaration.",
102 ));
103 }
104 };
105 Ok(ty)
106 }
107}
108
109pub fn bed_standard_autosql_fields() -> [AutosqlField; 12] {
114 [
115 AutosqlField {
116 name: "chrom".to_string(),
117 field_type: AutosqlType::String,
118 field_size: None,
119 index_type: None,
120 auto: false,
121 comment: "Reference sequence chromosome or scaffold.".to_string(),
122 },
123 AutosqlField {
124 name: "start".to_string(),
125 field_type: AutosqlType::Uint,
126 field_size: None,
127 index_type: None,
128 auto: false,
129 comment: "Start position in chromosome.".to_string(),
130 },
131 AutosqlField {
132 name: "end".to_string(),
133 field_type: AutosqlType::Uint,
134 field_size: None,
135 index_type: None,
136 auto: false,
137 comment: "End position in chromosome.".to_string(),
138 },
139 AutosqlField {
140 name: "name".to_string(),
141 field_type: AutosqlType::String,
142 field_size: None,
143 index_type: None,
144 auto: false,
145 comment: "Name or ID of item.".to_string(),
146 },
147 AutosqlField {
148 name: "score".to_string(),
149 field_type: AutosqlType::Ushort,
150 field_size: None,
151 index_type: None,
152 auto: false,
153 comment: "Score (0-1000).".to_string(),
154 },
155 AutosqlField {
156 name: "strand".to_string(),
157 field_type: AutosqlType::Char,
158 field_size: None,
159 index_type: None,
160 auto: false,
161 comment: "+ or - for strand.".to_string(),
162 },
163 AutosqlField {
164 name: "thickStart".to_string(),
165 field_type: AutosqlType::Uint,
166 field_size: None,
167 index_type: None,
168 auto: false,
169 comment: "Start of where display should be thick (start codon).".to_string(),
170 },
171 AutosqlField {
172 name: "thickEnd".to_string(),
173 field_type: AutosqlType::Uint,
174 field_size: None,
175 index_type: None,
176 auto: false,
177 comment: "End of where display should be thick (stop codon).".to_string(),
178 },
179 AutosqlField {
180 name: "itemRgb".to_string(),
181 field_type: AutosqlType::Ubyte,
182 field_size: Some("3".to_string()),
183 index_type: None,
184 auto: false,
185 comment: "RGB value (use R,G,B string in input file).".to_string(),
186 },
187 AutosqlField {
188 name: "blockCount".to_string(),
189 field_type: AutosqlType::Uint,
190 field_size: None,
191 index_type: None,
192 auto: false,
193 comment: "Number of blocks.".to_string(),
194 },
195 AutosqlField {
196 name: "blockSizes".to_string(),
197 field_type: AutosqlType::Uint,
198 field_size: Some("blockCount".to_string()),
199 index_type: None,
200 auto: false,
201 comment: "Comma separated list of block sizes.".to_string(),
202 },
203 AutosqlField {
204 name: "blockStarts".to_string(),
205 field_type: AutosqlType::Uint,
206 field_size: Some("blockCount".to_string()),
207 index_type: None,
208 auto: false,
209 comment: "Start positions relative to chromStart.".to_string(),
210 },
211 ]
212}
213
214#[cfg(test)]
215mod tests {
216 use super::*;
217
218 #[test]
219 fn test_fielddef_try_from_autosql_field() {
220 let autosql_field = AutosqlField {
221 name: "foo".to_string(),
222 field_type: AutosqlType::Int,
223 field_size: None,
224 index_type: None,
225 auto: false,
226 comment: "Just a field".to_string(),
227 };
228 let field_def = FieldDef::try_from(&autosql_field);
229 assert!(field_def.is_ok());
230 let field_def = field_def.unwrap();
231 assert_eq!(field_def.name, "foo");
232 assert_eq!(field_def.ty, FieldType::Int);
233 }
234}