@@ -9,6 +9,7 @@ use ansi_term::Colour::{Green, Red};
99use anyhow:: anyhow;
1010use base64:: Engine ;
1111use base64:: engine:: general_purpose:: STANDARD as BASE64 ;
12+ use bytes:: Bytes ;
1213use itertools:: Itertools ;
1314#[ cfg( feature = "xml" ) ] use kiss_xml:: dom:: Element ;
1415use maplit:: hashmap;
@@ -250,6 +251,14 @@ impl NodeValue {
250251 }
251252 }
252253
254+ /// If this value is a byte array, returns it, otherwise returns None
255+ pub fn as_bytes ( & self ) -> Option < & Vec < u8 > > {
256+ match self {
257+ NodeValue :: BARRAY ( b) => Some ( b) ,
258+ _ => None
259+ }
260+ }
261+
253262 /// Calculates an AND of two values
254263 pub fn and ( & self , other : & Self ) -> Self {
255264 match self {
@@ -386,8 +395,14 @@ impl From<&Element> for NodeValue {
386395
387396impl Matches < NodeValue > for NodeValue {
388397 fn matches_with ( & self , actual : NodeValue , matcher : & MatchingRule , cascaded : bool ) -> anyhow:: Result < ( ) > {
398+ self . matches_with ( & actual, matcher, cascaded)
399+ }
400+ }
401+
402+ impl Matches < & NodeValue > for NodeValue {
403+ fn matches_with ( & self , actual : & NodeValue , matcher : & MatchingRule , cascaded : bool ) -> anyhow:: Result < ( ) > {
389404 match self {
390- NodeValue :: NULL => Value :: Null . matches_with ( actual. as_json ( ) . unwrap_or_default ( ) , matcher, cascaded) ,
405+ NodeValue :: NULL => actual . matches_with ( actual, matcher, cascaded) ,
391406 NodeValue :: STRING ( s) => if let Some ( actual_str) = actual. as_string ( ) {
392407 s. matches_with ( actual_str, matcher, cascaded)
393408 } else if let Some ( list) = actual. as_slist ( ) {
@@ -425,6 +440,7 @@ impl Matches<NodeValue> for NodeValue {
425440 } else {
426441 Err ( anyhow ! ( "Was expecting an XML value but got {}" , actual) )
427442 } ,
443+ NodeValue :: BARRAY ( b) => Bytes :: new ( ) . matches_with ( Bytes :: copy_from_slice ( b. as_slice ( ) ) , matcher, cascaded) ,
428444 _ => Err ( anyhow ! ( "Matching rules can not be applied to {} values" , self . str_form( ) ) )
429445 }
430446 }
@@ -1298,6 +1314,22 @@ impl ExecutionPlan {
12981314 }
12991315}
13001316
1317+ impl From < ExecutionPlanNode > for ExecutionPlan {
1318+ fn from ( value : ExecutionPlanNode ) -> Self {
1319+ ExecutionPlan {
1320+ plan_root : value
1321+ }
1322+ }
1323+ }
1324+
1325+ impl From < & ExecutionPlanNode > for ExecutionPlan {
1326+ fn from ( value : & ExecutionPlanNode ) -> Self {
1327+ ExecutionPlan {
1328+ plan_root : value. clone ( )
1329+ }
1330+ }
1331+ }
1332+
13011333impl Into < Vec < Mismatch > > for ExecutionPlan {
13021334 fn into ( self ) -> Vec < Mismatch > {
13031335 let mut result = vec ! [ ] ;
@@ -1862,35 +1894,49 @@ fn setup_body_plan<T: HttpPart>(
18621894) -> anyhow:: Result < ExecutionPlanNode > {
18631895 // TODO: Look at the matching rules and generators here
18641896 let mut plan_node = ExecutionPlanNode :: container ( "body" ) ;
1897+ let body_path = DocPath :: body ( ) ;
18651898
18661899 match & expected. body ( ) {
18671900 OptionalBody :: Missing => { }
18681901 OptionalBody :: Empty | OptionalBody :: Null => {
18691902 plan_node. add ( ExecutionPlanNode :: action ( "expect:empty" )
1870- . add ( ExecutionPlanNode :: resolve_value ( DocPath :: new ( "$.body" ) ? ) ) ) ;
1903+ . add ( ExecutionPlanNode :: resolve_value ( body_path ) ) ) ;
18711904 }
18721905 OptionalBody :: Present ( content, _, _) => {
18731906 let content_type = expected. content_type ( ) . unwrap_or_else ( || TEXT . clone ( ) ) ;
1874- let mut content_type_check_node = ExecutionPlanNode :: action ( "if" ) ;
1875- content_type_check_node
1876- . add (
1877- ExecutionPlanNode :: action ( "match:equality" )
1878- . add ( ExecutionPlanNode :: value_node ( content_type. to_string ( ) ) )
1879- . add ( ExecutionPlanNode :: resolve_value ( DocPath :: new ( "$.content-type" ) ?) )
1880- . add ( ExecutionPlanNode :: value_node ( NodeValue :: NULL ) )
1881- . add (
1882- ExecutionPlanNode :: action ( "error" )
1883- . add ( ExecutionPlanNode :: value_node ( NodeValue :: STRING ( "Body type error - " . to_string ( ) ) ) )
1884- . add ( ExecutionPlanNode :: action ( "apply" ) )
1885- )
1886- ) ;
1887- if let Some ( plan_builder) = get_body_plan_builder ( & content_type) {
1888- content_type_check_node. add ( plan_builder. build_plan ( content, context) ?) ;
1907+ let root_matcher = expected. matching_rules ( )
1908+ . rules_for_category ( "body" )
1909+ . map ( |category| category. rules . get ( & DocPath :: root ( ) ) . cloned ( ) )
1910+ . flatten ( ) ;
1911+ if let Some ( root_matcher) = root_matcher && root_matcher. can_match ( & content_type) {
1912+ plan_node. add ( build_matching_rule_node (
1913+ & ExecutionPlanNode :: value_node ( NodeValue :: NULL ) ,
1914+ & ExecutionPlanNode :: resolve_value ( body_path) ,
1915+ & root_matcher,
1916+ false
1917+ ) ) ;
18891918 } else {
1890- let plan_builder = PlainTextBuilder :: new ( ) ;
1891- content_type_check_node. add ( plan_builder. build_plan ( content, context) ?) ;
1919+ let mut content_type_check_node = ExecutionPlanNode :: action ( "if" ) ;
1920+ content_type_check_node
1921+ . add (
1922+ ExecutionPlanNode :: action ( "match:equality" )
1923+ . add ( ExecutionPlanNode :: value_node ( content_type. to_string ( ) ) )
1924+ . add ( ExecutionPlanNode :: resolve_value ( DocPath :: new ( "$.content-type" ) ?) )
1925+ . add ( ExecutionPlanNode :: value_node ( NodeValue :: NULL ) )
1926+ . add (
1927+ ExecutionPlanNode :: action ( "error" )
1928+ . add ( ExecutionPlanNode :: value_node ( NodeValue :: STRING ( "Body type error - " . to_string ( ) ) ) )
1929+ . add ( ExecutionPlanNode :: action ( "apply" ) )
1930+ )
1931+ ) ;
1932+ if let Some ( plan_builder) = get_body_plan_builder ( & content_type) {
1933+ content_type_check_node. add ( plan_builder. build_plan ( content, context) ?) ;
1934+ } else {
1935+ let plan_builder = PlainTextBuilder :: new ( ) ;
1936+ content_type_check_node. add ( plan_builder. build_plan ( content, context) ?) ;
1937+ }
1938+ plan_node. add ( content_type_check_node) ;
18921939 }
1893- plan_node. add ( content_type_check_node) ;
18941940 }
18951941 }
18961942
0 commit comments