22use std:: { borrow:: Cow , cell:: RefCell , fmt:: Write as FmtWrite } ;
33
44use nanorand:: { Rng , WyRand } ;
5- use ntex:: util:: { BufMut , Bytes , BytesMut } ;
6- use smallvec:: SmallVec ;
5+ use ntex:: util:: { Bytes , BytesMut } ;
76use tokio_postgres:: types:: ToSql ;
87use tokio_postgres:: { connect, Client , Statement } ;
9- use yarte:: { ywrite_html , Serialize } ;
8+ use yarte:: TemplateBytesTrait ;
109
1110use super :: utils;
1211
13- #[ derive( Copy , Clone , Serialize , Debug ) ]
12+ #[ derive( Copy , Clone , Debug , sonic_rs :: Serialize ) ]
1413pub struct World {
1514 pub id : i32 ,
1615 pub randomnumber : i32 ,
1716}
1817
19- #[ derive( Serialize , Debug ) ]
18+ #[ derive( Debug , sonic_rs :: Serialize ) ]
2019pub struct Fortune {
2120 pub id : i32 ,
2221 pub message : Cow < ' static , str > ,
2322}
2423
24+ #[ derive( yarte:: TemplateBytes ) ]
25+ #[ template( path = "fortune.hbs" ) ]
26+ pub struct FortunesTemplate < ' a > {
27+ pub fortunes : & ' a Vec < Fortune > ,
28+ }
29+
2530/// Postgres interface
2631pub struct PgConnection {
2732 cl : Client ,
@@ -30,6 +35,7 @@ pub struct PgConnection {
3035 rng : WyRand ,
3136 updates : Vec < Statement > ,
3237 buf : RefCell < BytesMut > ,
38+ fbuf : RefCell < Vec < Fortune > > ,
3339}
3440
3541impl PgConnection {
@@ -69,6 +75,7 @@ impl PgConnection {
6975 updates,
7076 rng : WyRand :: new ( ) ,
7177 buf : RefCell :: new ( BytesMut :: with_capacity ( 10 * 1024 * 1024 ) ) ,
78+ fbuf : RefCell :: new ( Vec :: with_capacity ( 64 ) ) ,
7279 }
7380 }
7481}
@@ -81,23 +88,26 @@ impl PgConnection {
8188
8289 let mut body = self . buf . borrow_mut ( ) ;
8390 utils:: reserve ( & mut body, 1024 ) ;
84- World {
85- id : row. get ( 0 ) ,
86- randomnumber : row. get ( 1 ) ,
87- }
88- . to_bytes_mut ( & mut * body) ;
91+ sonic_rs:: to_writer (
92+ utils:: BytesWriter ( & mut body) ,
93+ & World {
94+ id : row. get ( 0 ) ,
95+ randomnumber : row. get ( 1 ) ,
96+ } ,
97+ )
98+ . unwrap ( ) ;
8999 body. split ( ) . freeze ( )
90100 }
91101
92102 pub async fn get_worlds ( & self , num : usize ) -> Bytes {
93103 let mut rng = self . rng . clone ( ) ;
94- let mut queries = SmallVec :: < [ _ ; 32 ] > :: new ( ) ;
104+ let mut queries = Vec :: with_capacity ( num ) ;
95105 ( 0 ..num) . for_each ( |_| {
96106 let w_id = ( rng. generate :: < u32 > ( ) % 10_000 + 1 ) as i32 ;
97107 queries. push ( self . cl . query_one ( & self . world , & [ & w_id] ) ) ;
98108 } ) ;
99109
100- let mut worlds = SmallVec :: < [ _ ; 32 ] > :: new ( ) ;
110+ let mut worlds = Vec :: with_capacity ( num ) ;
101111 for fut in queries {
102112 let row = fut. await . unwrap ( ) ;
103113 worlds. push ( World {
@@ -108,25 +118,19 @@ impl PgConnection {
108118
109119 let mut body = self . buf . borrow_mut ( ) ;
110120 utils:: reserve ( & mut body, 2 * 1024 ) ;
111- body. put_u8 ( b'[' ) ;
112- worlds. iter ( ) . for_each ( |w| {
113- w. to_bytes_mut ( & mut * body) ;
114- body. put_u8 ( b',' ) ;
115- } ) ;
116- let idx = body. len ( ) - 1 ;
117- body[ idx] = b']' ;
121+ sonic_rs:: to_writer ( utils:: BytesWriter ( & mut body) , & worlds[ ..] ) . unwrap ( ) ;
118122 body. split ( ) . freeze ( )
119123 }
120124
121125 pub async fn update ( & self , num : usize ) -> Bytes {
122126 let mut rng = nanorand:: tls_rng ( ) ;
123- let mut queries = SmallVec :: < [ _ ; 32 ] > :: new ( ) ;
127+ let mut queries = Vec :: with_capacity ( num ) ;
124128 ( 0 ..num) . for_each ( |_| {
125129 let w_id = ( rng. generate :: < u32 > ( ) % 10_000 + 1 ) as i32 ;
126130 queries. push ( self . cl . query_one ( & self . world , & [ & w_id] ) ) ;
127131 } ) ;
128132
129- let mut worlds = SmallVec :: < [ _ ; 32 ] > :: new ( ) ;
133+ let mut worlds = Vec :: with_capacity ( num ) ;
130134 for fut in queries. into_iter ( ) {
131135 let row = fut. await . unwrap ( ) ;
132136 worlds. push ( World {
@@ -147,23 +151,18 @@ impl PgConnection {
147151
148152 let mut body = self . buf . borrow_mut ( ) ;
149153 utils:: reserve ( & mut body, 2 * 1024 ) ;
150- body. put_u8 ( b'[' ) ;
151- worlds. iter ( ) . for_each ( |w| {
152- w. to_bytes_mut ( & mut * body) ;
153- body. put_u8 ( b',' ) ;
154- } ) ;
155- let idx = body. len ( ) - 1 ;
156- body[ idx] = b']' ;
154+ sonic_rs:: to_writer ( utils:: BytesWriter ( & mut body) , & worlds[ ..] ) . unwrap ( ) ;
157155 body. split ( ) . freeze ( )
158156 }
159157
160158 pub async fn tell_fortune ( & self ) -> Bytes {
161159 let rows = self . cl . query_raw ( & self . fortune , & [ ] ) . await . unwrap ( ) ;
162160
163- let mut fortunes: SmallVec < [ _ ; 32 ] > = smallvec:: smallvec![ Fortune {
161+ let mut fortunes = self . fbuf . borrow_mut ( ) ;
162+ fortunes. push ( Fortune {
164163 id : 0 ,
165164 message : Cow :: Borrowed ( "Additional fortune added at request time." ) ,
166- } ] ;
165+ } ) ;
167166 fortunes. extend ( rows. iter ( ) . map ( |row| Fortune {
168167 id : row. get ( 0 ) ,
169168 message : Cow :: Owned ( row. get ( 1 ) ) ,
@@ -172,7 +171,13 @@ impl PgConnection {
172171
173172 let mut body = std:: mem:: replace ( & mut * self . buf . borrow_mut ( ) , BytesMut :: new ( ) ) ;
174173 utils:: reserve ( & mut body, 4 * 1024 ) ;
175- ywrite_html ! ( body, "{{> fortune }}" ) ;
174+
175+ FortunesTemplate {
176+ fortunes : & * fortunes,
177+ }
178+ . write_call ( & mut body) ;
179+ fortunes. clear ( ) ;
180+
176181 let result = body. split ( ) . freeze ( ) ;
177182 let _ = std:: mem:: replace ( & mut * self . buf . borrow_mut ( ) , body) ;
178183 result
0 commit comments