11use std:: error:: Error ;
2- use std:: fmt;
3- use std:: mem;
4-
5- use yaml_rust as yaml;
62
73use crate :: format;
84use crate :: map:: Map ;
@@ -12,94 +8,53 @@ pub fn parse(
128 uri : Option < & String > ,
139 text : & str ,
1410) -> Result < Map < String , Value > , Box < dyn Error + Send + Sync > > {
15- // Parse a YAML object from file
16- let mut docs = yaml:: YamlLoader :: load_from_str ( text) ?;
17- let root = match docs. len ( ) {
18- 0 => yaml:: Yaml :: Hash ( yaml:: yaml:: Hash :: new ( ) ) ,
19- 1 => mem:: replace ( & mut docs[ 0 ] , yaml:: Yaml :: Null ) ,
20- n => {
21- return Err ( Box :: new ( MultipleDocumentsError ( n) ) ) ;
22- }
23- } ;
24-
25- let value = from_yaml_value ( uri, & root) ?;
11+ // Parse a YAML input from the provided text
12+ let value = from_yaml_value ( uri, serde_yaml:: from_str ( text) ?) ;
2613 format:: extract_root_table ( uri, value)
2714}
2815
29- fn from_yaml_value (
30- uri : Option < & String > ,
31- value : & yaml:: Yaml ,
32- ) -> Result < Value , Box < dyn Error + Send + Sync > > {
33- match * value {
34- yaml:: Yaml :: String ( ref value) => Ok ( Value :: new ( uri, ValueKind :: String ( value. clone ( ) ) ) ) ,
35- yaml:: Yaml :: Real ( ref value) => {
36- // TODO: Figure out in what cases this can panic?
37- value
38- . parse :: < f64 > ( )
39- . map_err ( |_| {
40- Box :: new ( FloatParsingError ( value. to_string ( ) ) ) as Box < ( dyn Error + Send + Sync ) >
41- } )
42- . map ( ValueKind :: Float )
43- . map ( |f| Value :: new ( uri, f) )
44- }
45- yaml:: Yaml :: Integer ( value) => Ok ( Value :: new ( uri, ValueKind :: I64 ( value) ) ) ,
46- yaml:: Yaml :: Boolean ( value) => Ok ( Value :: new ( uri, ValueKind :: Boolean ( value) ) ) ,
47- yaml:: Yaml :: Hash ( ref table) => {
48- let mut m = Map :: new ( ) ;
49- for ( key, value) in table {
50- match key {
51- yaml:: Yaml :: String ( k) => m. insert ( k. to_owned ( ) , from_yaml_value ( uri, value) ?) ,
52- yaml:: Yaml :: Integer ( k) => m. insert ( k. to_string ( ) , from_yaml_value ( uri, value) ?) ,
53- _ => unreachable ! ( ) ,
54- } ;
16+ pub fn from_yaml_value ( uri : Option < & String > , value : serde_yaml:: Value ) -> Value {
17+ let vk = match value {
18+ serde_yaml:: Value :: Tagged ( _) | serde_yaml:: Value :: Null => ValueKind :: Nil ,
19+ serde_yaml:: Value :: Bool ( v) => ValueKind :: Boolean ( v) ,
20+ serde_yaml:: Value :: String ( v) => ValueKind :: String ( v) ,
21+
22+ serde_yaml:: Value :: Number ( v) => {
23+ if v. is_i64 ( ) {
24+ ValueKind :: I64 ( v. as_i64 ( ) . expect ( "i64" ) )
25+ } else if v. is_u64 ( ) {
26+ ValueKind :: U64 ( v. as_u64 ( ) . expect ( "u64" ) )
27+ } else if v. is_f64 ( ) {
28+ ValueKind :: Float ( v. as_f64 ( ) . expect ( "f64" ) )
29+ } else {
30+ ValueKind :: Nil
5531 }
56- Ok ( Value :: new ( uri, ValueKind :: Table ( m) ) )
5732 }
58- yaml:: Yaml :: Array ( ref array) => {
59- let mut l = Vec :: new ( ) ;
6033
61- for value in array {
62- l. push ( from_yaml_value ( uri, value) ?) ;
63- }
34+ serde_yaml:: Value :: Mapping ( table) => {
35+ let m = table
36+ . into_iter ( )
37+ . map ( |( k, v) | {
38+ let key = match k {
39+ serde_yaml:: Value :: Number ( v) => v. to_string ( ) ,
40+ serde_yaml:: Value :: String ( v) => v,
41+
42+ _ => unreachable ! ( ) ,
43+ } ;
44+ let value = from_yaml_value ( uri, v) ;
45+ ( key, value)
46+ } )
47+ . collect ( ) ;
6448
65- Ok ( Value :: new ( uri , ValueKind :: Array ( l ) ) )
49+ ValueKind :: Table ( m )
6650 }
6751
68- // 1. Yaml NULL
69- // 2. BadValue – It shouldn't be possible to hit BadValue as this only happens when
70- // using the index trait badly or on a type error but we send back nil.
71- // 3. Alias – No idea what to do with this and there is a note in the lib that its
72- // not fully supported yet anyway
73- _ => Ok ( Value :: new ( uri, ValueKind :: Nil ) ) ,
74- }
75- }
52+ serde_yaml:: Value :: Sequence ( array) => {
53+ let l = array. into_iter ( ) . map ( |v| from_yaml_value ( uri, v) ) . collect ( ) ;
7654
77- #[ derive( Debug , Copy , Clone ) ]
78- struct MultipleDocumentsError ( usize ) ;
79-
80- impl fmt:: Display for MultipleDocumentsError {
81- fn fmt ( & self , format : & mut fmt:: Formatter ) -> fmt:: Result {
82- write ! ( format, "Got {} YAML documents, expected 1" , self . 0 )
83- }
84- }
85-
86- impl Error for MultipleDocumentsError {
87- fn description ( & self ) -> & str {
88- "More than one YAML document provided"
89- }
90- }
91-
92- #[ derive( Debug , Clone ) ]
93- struct FloatParsingError ( String ) ;
94-
95- impl fmt:: Display for FloatParsingError {
96- fn fmt ( & self , format : & mut fmt:: Formatter ) -> fmt:: Result {
97- write ! ( format, "Parsing {} as floating point number failed" , self . 0 )
98- }
99- }
55+ ValueKind :: Array ( l)
56+ }
57+ } ;
10058
101- impl Error for FloatParsingError {
102- fn description ( & self ) -> & str {
103- "Floating point number parsing failed"
104- }
59+ Value :: new ( uri, vk)
10560}
0 commit comments