@@ -15,15 +15,22 @@ use time::OffsetDateTime;
15
15
static COLLECTION_TEMPLATE : & str = include_str ! ( "templates/collection.html.tera" ) ;
16
16
17
17
/// A template manager
18
- pub ( crate ) struct Templater ( Tera ) ;
18
+ pub ( crate ) struct Templater {
19
+ /// Tera templater
20
+ engine : Tera ,
21
+
22
+ /// Site title to display in HTML responses
23
+ title : String ,
24
+ }
19
25
20
26
impl Templater {
21
- /// Create a new templater and load all templates into it
27
+ /// Create a new templater with site title `title` and load all templates
28
+ /// into it
22
29
///
23
30
/// # Errors
24
31
///
25
32
/// If any template fails to load, a [`TemplateError::Load`] is returned.
26
- pub ( crate ) fn load ( ) -> Result < Self , TemplateError > {
33
+ pub ( crate ) fn new ( title : String ) -> Result < Self , TemplateError > {
27
34
let mut engine = Tera :: default ( ) ;
28
35
engine. register_filter ( "formatsize" , FormatSizeFilter ) ;
29
36
engine
@@ -32,37 +39,77 @@ impl Templater {
32
39
template_name : "collection.html" ,
33
40
source,
34
41
} ) ?;
35
- Ok ( Templater ( engine) )
42
+ Ok ( Templater { engine, title } )
36
43
}
37
44
38
45
/// Render an HTML document containing a table listing the resources in
39
- /// `entries` using the site title `title` . `pathparts` contains the
40
- /// individual components of the request URL path.
46
+ /// `entries`. `pathparts` contains the individual components of the
47
+ /// request URL path.
41
48
pub ( super ) fn render_collection (
42
49
& self ,
43
50
entries : Vec < DavResource > ,
44
- title : & str ,
45
51
pathparts : Vec < Component > ,
46
52
) -> Result < String , TemplateError > {
47
- self . render_collection_from_context ( CollectionContext :: new ( entries, title, pathparts) )
48
- }
49
-
50
- fn render_collection_from_context (
51
- & self ,
52
- context : CollectionContext ,
53
- ) -> Result < String , TemplateError > {
53
+ let template_name = "collection.html" ;
54
+ let colctx = self . collection_context ( entries, pathparts) ;
54
55
let context =
55
- Context :: from_serialize ( context ) . map_err ( |source| TemplateError :: MakeContext {
56
- template_name : "collection.html" ,
56
+ Context :: from_serialize ( colctx ) . map_err ( |source| TemplateError :: MakeContext {
57
+ template_name,
57
58
source,
58
59
} ) ?;
59
- self . 0
60
- . render ( "collection.html" , & context)
60
+ self . engine
61
+ . render ( template_name , & context)
61
62
. map_err ( |source| TemplateError :: Render {
62
- template_name : "collection.html" ,
63
+ template_name,
63
64
source,
64
65
} )
65
66
}
67
+
68
+ /// Construct the context for displaying the given `entries`. `pathparts`
69
+ /// contains the individual components of the request URL path.
70
+ fn collection_context (
71
+ & self ,
72
+ entries : Vec < DavResource > ,
73
+ pathparts : Vec < Component > ,
74
+ ) -> CollectionContext {
75
+ let mut rows = entries. into_iter ( ) . map ( ColRow :: from) . collect :: < Vec < _ > > ( ) ;
76
+ rows. sort_unstable ( ) ;
77
+ if let Some ( ( _, pp) ) = pathparts. split_last ( ) {
78
+ rows. insert (
79
+ 0 ,
80
+ ColRow :: parentdir ( Href :: from_path ( & abs_dir_from_components ( pp) ) ) ,
81
+ ) ;
82
+ }
83
+ let title_path = abs_dir_from_components ( & pathparts) ;
84
+ let title = format ! ( "{} \u{2014} {}" , self . title, title_path) ;
85
+ CollectionContext {
86
+ title,
87
+ breadcrumbs : self . make_breadcrumbs ( pathparts) ,
88
+ rows,
89
+ package_url : env ! ( "CARGO_PKG_REPOSITORY" ) ,
90
+ package_version : env ! ( "CARGO_PKG_VERSION" ) ,
91
+ package_commit : option_env ! ( "GIT_COMMIT" ) ,
92
+ }
93
+ }
94
+
95
+ /// Create breadcrumbs for the given request URL path components
96
+ fn make_breadcrumbs ( & self , pathparts : Vec < Component > ) -> Vec < Link > {
97
+ let mut links = Vec :: with_capacity ( pathparts. len ( ) . saturating_add ( 1 ) ) ;
98
+ let mut cumpath = String :: from ( "/" ) ;
99
+ links. push ( Link {
100
+ text : self . title . clone ( ) ,
101
+ href : Href :: from_path ( & cumpath) ,
102
+ } ) ;
103
+ for p in pathparts {
104
+ cumpath. push_str ( & p) ;
105
+ cumpath. push ( '/' ) ;
106
+ links. push ( Link {
107
+ text : p. into ( ) ,
108
+ href : Href :: from_path ( & cumpath) ,
109
+ } ) ;
110
+ }
111
+ links
112
+ }
66
113
}
67
114
68
115
/// Context to provide to the `collection.html` template
@@ -88,32 +135,6 @@ struct CollectionContext {
88
135
package_commit : Option < & ' static str > ,
89
136
}
90
137
91
- impl CollectionContext {
92
- /// Construct the context for displaying the given `entries` using the site
93
- /// title `title`. `pathparts` contains the individual components of the
94
- /// request URL path.
95
- fn new ( entries : Vec < DavResource > , title : & str , pathparts : Vec < Component > ) -> CollectionContext {
96
- let mut rows = entries. into_iter ( ) . map ( ColRow :: from) . collect :: < Vec < _ > > ( ) ;
97
- rows. sort_unstable ( ) ;
98
- if let Some ( ( _, pp) ) = pathparts. split_last ( ) {
99
- rows. insert (
100
- 0 ,
101
- ColRow :: parentdir ( Href :: from_path ( & abs_dir_from_components ( pp) ) ) ,
102
- ) ;
103
- }
104
- let title_path = abs_dir_from_components ( & pathparts) ;
105
- let full_title = format ! ( "{title} \u{2014} {title_path}" ) ;
106
- CollectionContext {
107
- title : full_title,
108
- breadcrumbs : make_breadcrumbs ( title, pathparts) ,
109
- rows,
110
- package_url : env ! ( "CARGO_PKG_REPOSITORY" ) ,
111
- package_version : env ! ( "CARGO_PKG_VERSION" ) ,
112
- package_commit : option_env ! ( "GIT_COMMIT" ) ,
113
- }
114
- }
115
- }
116
-
117
138
/// A hyperlink to display in an HTML document
118
139
#[ derive( Clone , Debug , Eq , PartialEq , Serialize ) ]
119
140
struct Link {
@@ -165,7 +186,7 @@ struct ColRow {
165
186
166
187
impl ColRow {
167
188
/// Construct a `ColRow` representing the parent of the current collection,
168
- /// served at `href`
189
+ /// with the parent being served at `href`
169
190
fn parentdir ( href : Href ) -> ColRow {
170
191
ColRow {
171
192
name : ".." . to_owned ( ) ,
@@ -261,27 +282,6 @@ fn maybe_timestamp<S: Serializer>(
261
282
}
262
283
}
263
284
264
- /// Create breadcrumbs for the given request URL path components.
265
- ///
266
- /// `title` is the site title, for use as the text of the first breadcrumb.
267
- fn make_breadcrumbs ( title : & str , pathparts : Vec < Component > ) -> Vec < Link > {
268
- let mut links = Vec :: with_capacity ( pathparts. len ( ) . saturating_add ( 1 ) ) ;
269
- let mut cumpath = String :: from ( "/" ) ;
270
- links. push ( Link {
271
- text : title. to_owned ( ) ,
272
- href : Href :: from_path ( & cumpath) ,
273
- } ) ;
274
- for p in pathparts {
275
- cumpath. push_str ( & p) ;
276
- cumpath. push ( '/' ) ;
277
- links. push ( Link {
278
- text : p. into ( ) ,
279
- href : Href :: from_path ( & cumpath) ,
280
- } ) ;
281
- }
282
- links
283
- }
284
-
285
285
/// Given an iterator of `&Component` values, join them together with forward
286
286
/// slashes and add a leading & trailing slash.
287
287
fn abs_dir_from_components < ' a , I > ( iter : I ) -> String
@@ -344,7 +344,7 @@ mod tests {
344
344
assert_eq ! ( formatsize( size) , s) ;
345
345
}
346
346
347
- mod render_collection_from_context {
347
+ mod render_collection {
348
348
use super :: * ;
349
349
use crate :: dav:: { DavContent , DavResourceWithChildren } ;
350
350
use pretty_assertions:: assert_eq;
@@ -353,7 +353,7 @@ mod tests {
353
353
354
354
#[ test]
355
355
fn basic ( ) {
356
- let templater = Templater :: load ( ) . unwrap ( ) ;
356
+ let templater = Templater :: new ( "Dandidav Test" . to_owned ( ) ) . unwrap ( ) ;
357
357
let entries = vec ! [
358
358
DavResource :: Collection ( DavCollection {
359
359
path: Some ( "foo/bar/baz/a.zarr/" . parse( ) . unwrap( ) ) ,
@@ -421,16 +421,16 @@ mod tests {
421
421
metadata_url: None ,
422
422
} ) ,
423
423
] ;
424
- let context = CollectionContext :: new (
425
- entries ,
426
- "Dandidav Test" ,
427
- vec ! [
428
- "foo" . parse( ) . unwrap( ) ,
429
- "bar" . parse( ) . unwrap( ) ,
430
- "baz" . parse( ) . unwrap( ) ,
431
- ] ,
432
- ) ;
433
- let rendered = templater . render_collection_from_context ( context ) . unwrap ( ) ;
424
+ let rendered = templater
425
+ . render_collection (
426
+ entries ,
427
+ vec ! [
428
+ "foo" . parse( ) . unwrap( ) ,
429
+ "bar" . parse( ) . unwrap( ) ,
430
+ "baz" . parse( ) . unwrap( ) ,
431
+ ] ,
432
+ )
433
+ . unwrap ( ) ;
434
434
let commit_str = match option_env ! ( "GIT_COMMIT" ) {
435
435
Some ( s) => Cow :: from ( format ! ( ", commit {s}" ) ) ,
436
436
None => Cow :: from ( "" ) ,
@@ -451,14 +451,13 @@ mod tests {
451
451
452
452
#[ test]
453
453
fn root ( ) {
454
- let templater = Templater :: load ( ) . unwrap ( ) ;
454
+ let templater = Templater :: new ( "Dandidav Test" . to_owned ( ) ) . unwrap ( ) ;
455
455
let DavResourceWithChildren :: Collection { children, .. } =
456
456
DavResourceWithChildren :: root ( )
457
457
else {
458
458
panic ! ( "DavResourceWithChildren::root() should be a Collection" ) ;
459
459
} ;
460
- let context = CollectionContext :: new ( children, "Dandidav Test" , Vec :: new ( ) ) ;
461
- let rendered = templater. render_collection_from_context ( context) . unwrap ( ) ;
460
+ let rendered = templater. render_collection ( children, Vec :: new ( ) ) . unwrap ( ) ;
462
461
let commit_str = match option_env ! ( "GIT_COMMIT" ) {
463
462
Some ( s) => Cow :: from ( format ! ( ", commit {s}" ) ) ,
464
463
None => Cow :: from ( "" ) ,
0 commit comments