1
+ use context:: Context ;
2
+ use error:: { Error , Result } ;
3
+ use lexer:: Element ;
4
+ use LiquidOptions ;
5
+ use Renderable ;
6
+ use template:: Template ;
7
+ use token:: Token :: { self , Identifier } ;
8
+ use value:: Value ;
9
+ use parser:: parse;
10
+
11
+ struct Capture {
12
+ id : String ,
13
+ template : Template
14
+ }
15
+
16
+ impl Renderable for Capture {
17
+ fn render ( & self , context : & mut Context ) -> Result < Option < String > > {
18
+ let output = match self . template . render ( context) {
19
+ Ok ( Some ( s) ) => s. clone ( ) ,
20
+ Ok ( None ) => "" . to_owned ( ) ,
21
+ Err ( x) => return Err ( x)
22
+ } ;
23
+
24
+ context. set_val ( & self . id , Value :: Str ( output) ) ;
25
+ Ok ( None )
26
+ }
27
+ }
28
+
29
+ pub fn capture_block ( _tag_name : & str ,
30
+ arguments : & [ Token ] ,
31
+ tokens : Vec < Element > ,
32
+ options : & LiquidOptions )
33
+ -> Result < Box < Renderable > > {
34
+ let mut args = arguments. iter ( ) ;
35
+ let id = match args. next ( ) {
36
+ Some ( & Identifier ( ref x) ) => x. clone ( ) ,
37
+ x @ Some ( _) | x @ None => {
38
+ return Error :: parser ( "Identifier" , x)
39
+ }
40
+ } ;
41
+
42
+ // there should be no trailing tokens after this
43
+ if let t @ Some ( _) = args. next ( ) {
44
+ return Error :: parser ( "%}" , t)
45
+ } ;
46
+
47
+ let t = Template :: new ( try!( parse ( & tokens, options) ) ) ;
48
+
49
+ Ok ( Box :: new ( Capture {
50
+ id : id,
51
+ template : t
52
+ } ) )
53
+ }
54
+
55
+ #[ cfg( test) ]
56
+ mod test {
57
+ use parse;
58
+ use LiquidOptions ;
59
+ use Renderable ;
60
+ use value:: Value ;
61
+ use std:: default:: Default ;
62
+ use context:: Context ;
63
+
64
+ #[ test]
65
+ fn test_capture ( ) {
66
+ let text = concat ! (
67
+ "{% capture attribute_name %}" ,
68
+ "{{ item | upcase }}-{{ i }}-color" ,
69
+ "{% endcapture %}" ) ;
70
+ let template = parse ( text, LiquidOptions :: default ( ) ) . unwrap ( ) ;
71
+
72
+ let mut ctx = Context :: new ( ) ;
73
+ ctx. set_val ( "item" , Value :: str ( "potato" ) ) ;
74
+ ctx. set_val ( "i" , Value :: Num ( 42f32 ) ) ;
75
+
76
+ let output = template. render ( & mut ctx) ;
77
+ assert_eq ! ( output. unwrap( ) , Some ( "" . to_owned( ) ) ) ;
78
+ assert_eq ! ( ctx. get_val( "attribute_name" ) ,
79
+ Some ( & Value :: str ( "POTATO-42-color" ) ) ) ;
80
+ }
81
+
82
+ #[ test]
83
+ fn trailing_tokens_are_an_error ( ) {
84
+ let text = concat ! (
85
+ "{% capture foo bar baz %}" ,
86
+ "We should never see this" ,
87
+ "{% endcapture %}" ) ;
88
+ assert ! ( parse( text, LiquidOptions :: default ( ) ) . is_err( ) ) ;
89
+ }
90
+ }
0 commit comments