| 1 | use crate::error::{Error, Result}; | 
| 2 | use crate::iter::Iter; | 
|---|
| 3 | use crate::token; | 
|---|
| 4 | use proc_macro::Group; | 
|---|
| 5 |  | 
|---|
| 6 | #[ derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] | 
|---|
| 7 | pub struct Release { | 
|---|
| 8 | pub minor: u16, | 
|---|
| 9 | pub patch: Option<u16>, | 
|---|
| 10 | } | 
|---|
| 11 |  | 
|---|
| 12 | pub fn parse(paren: Group, iter: Iter) -> Result<Release> { | 
|---|
| 13 | try_parse(iter).map_err(|()| Error::group(group:paren, msg: "expected rustc release number, like 1.31")) | 
|---|
| 14 | } | 
|---|
| 15 |  | 
|---|
| 16 | fn try_parse(iter: Iter) -> Result<Release, ()> { | 
|---|
| 17 | let major_minor: Literal = token::parse_literal(iter).map_err(op:drop)?; | 
|---|
| 18 | let string: String = major_minor.to_string(); | 
|---|
| 19 |  | 
|---|
| 20 | if !string.starts_with( "1.") { | 
|---|
| 21 | return Err(()); | 
|---|
| 22 | } | 
|---|
| 23 |  | 
|---|
| 24 | let minor: u16 = string[2..].parse().map_err(op:drop)?; | 
|---|
| 25 |  | 
|---|
| 26 | let patch: Option = if token::parse_optional_punct(iter, ch: '.').is_some() { | 
|---|
| 27 | let int: Literal = token::parse_literal(iter).map_err(op:drop)?; | 
|---|
| 28 | Some(int.to_string().parse().map_err(op:drop)?) | 
|---|
| 29 | } else { | 
|---|
| 30 | None | 
|---|
| 31 | }; | 
|---|
| 32 |  | 
|---|
| 33 | Ok(Release { minor, patch }) | 
|---|
| 34 | } | 
|---|
| 35 |  | 
|---|