| 1332 | } |
| 1333 | |
| 1334 | pub fn parse_analyses(input: ParseStream) -> syn::Result<Analyses> { |
| 1335 | let mut analyses = Analyses::default(); |
| 1336 | |
| 1337 | // Analyses are optional, appearing after a `//` at the end of the |
| 1338 | // line. However, since the syn lexer eats comments, we assume that `//` |
| 1339 | // was replaced with `::` upfront. |
| 1340 | if input.eat(syn::Token![::]) { |
| 1341 | let inner; |
| 1342 | syn::braced!(inner in input); |
| 1343 | |
| 1344 | let (start, end) = (inner.span().start(), inner.span().end()); |
| 1345 | if start.line != end.line { |
| 1346 | let msg = "analyses should not span more than one line".to_string(); |
| 1347 | Err(Error::new(inner.span(), msg))? |
| 1348 | } |
| 1349 | |
| 1350 | while inner.peek(syn::Ident) { |
| 1351 | let ident = inner.parse::<syn::Ident>()?.to_string(); |
| 1352 | match ident.as_str() { |
| 1353 | "types" => { |
| 1354 | inner.parse::<syn::Token![:]>()?; |
| 1355 | let value = inner.parse::<syn::LitStr>()?.value(); |
| 1356 | analyses.types = Some(parse_types.parse_str(&value)?); |
| 1357 | } |
| 1358 | // TODO: support keys |
| 1359 | key => { |
| 1360 | let msg = format!("unexpected analysis type `{}`", key); |
| 1361 | Err(Error::new(inner.span(), msg))?; |
| 1362 | } |
| 1363 | } |
| 1364 | } |
| 1365 | } |
| 1366 | Ok(analyses) |
| 1367 | } |
| 1368 | |
| 1369 | fn parse_types(input: ParseStream) -> syn::Result<Vec<ReprColumnType>> { |
| 1370 | let inner; |