1
1
use std:: error:: Error ;
2
- use std:: fmt;
3
- use std:: mem;
4
-
5
- use yaml_rust as yaml;
6
2
7
3
use crate :: format;
8
4
use crate :: map:: Map ;
@@ -12,94 +8,53 @@ pub fn parse(
12
8
uri : Option < & String > ,
13
9
text : & str ,
14
10
) -> 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) ?) ;
26
13
format:: extract_root_table ( uri, value)
27
14
}
28
15
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
55
31
}
56
- Ok ( Value :: new ( uri, ValueKind :: Table ( m) ) )
57
32
}
58
- yaml:: Yaml :: Array ( ref array) => {
59
- let mut l = Vec :: new ( ) ;
60
33
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 ( ) ;
64
48
65
- Ok ( Value :: new ( uri , ValueKind :: Array ( l ) ) )
49
+ ValueKind :: Table ( m )
66
50
}
67
51
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 ( ) ;
76
54
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
+ } ;
100
58
101
- impl Error for FloatParsingError {
102
- fn description ( & self ) -> & str {
103
- "Floating point number parsing failed"
104
- }
59
+ Value :: new ( uri, vk)
105
60
}
0 commit comments