pub struct Template<V, R, FS>{ /* private fields */ }Expand description
Template holder for materializing templates into files.
Orchestrates the entire template processing pipeline: reads templates, applies values, renders content, and writes to files using pluggable filesystem and renderer implementations.
Generic over value type V and renderer type R for maximum flexibility.
§Type Parameters
V: Value type implementingTemplateValuetraitR: Renderer implementingTemplateRenderertraitFS: File system implementingFileSystemtrait
§Examples
use genfile_core::{ Template, HandlebarsRenderer, MemoryFileSystem, Value, FileDescriptor, WriteMode };
use std::path::PathBuf;
let renderer = HandlebarsRenderer::new();
let mut filesystem = MemoryFileSystem::new();
// Set up template
filesystem.write( &PathBuf::from( "template.hbs" ), "Hello {{name}}!" )?;
let mut template = Template::new( renderer, filesystem );
template.insert_value( "name", Value::String( "World".into() ) );
template.add_file( FileDescriptor
{
file_path: PathBuf::from( "output.txt" ),
template_path: PathBuf::from( "template.hbs" ),
write_mode: WriteMode::Rewrite,
});
template.materialize()?;Implementations§
Source§impl<V, R, FS> Template<V, R, FS>
impl<V, R, FS> Template<V, R, FS>
Sourcepub fn new(renderer: R, filesystem: FS) -> Self
pub fn new(renderer: R, filesystem: FS) -> Self
Creates a new template with the given renderer and filesystem.
§Parameters
renderer: Template rendering enginefilesystem: File system for I/O operations
§Returns
New Template instance
§Examples
use genfile_core::{ Template, HandlebarsRenderer, MemoryFileSystem, Value };
let renderer = HandlebarsRenderer::new();
let filesystem = MemoryFileSystem::new();
let template: Template< Value, _, _ > = Template::new( renderer, filesystem );Examples found in repository?
20fn main() -> Result< (), Box< dyn core::error::Error > >
21{
22 println!( "=== Low-Level Template API Example ===" );
23 println!();
24
25 // Create renderer
26 let renderer = HandlebarsRenderer::new();
27
28 // Create two separate filesystems: one for templates, one for output
29 let mut template_fs = MemoryFileSystem::new();
30
31 // Prepare template files in the template filesystem
32 template_fs.write(
33 &PathBuf::from( "/templates/greeting.hbs" ),
34 "Hello, {{name}}!\n"
35 )?;
36
37 template_fs.write(
38 &PathBuf::from( "/templates/config.hbs" ),
39 "server={{server}}\nport={{port}}\n"
40 )?;
41
42 println!( "Template files prepared in memory filesystem" );
43 println!();
44
45 // Create template with explicit types using the template filesystem
46 let mut template = Template::< Value, _, _ >::new( renderer, template_fs );
47
48 // Insert values
49 template.insert_value( "name", Value::String( "World".into() ) );
50 template.insert_value( "server", Value::String( "localhost".into() ) );
51 template.insert_value( "port", Value::Number( 8080 ) );
52
53 // Add file descriptors
54 template.add_file( FileDescriptor
55 {
56 template_path: PathBuf::from( "/templates/greeting.hbs" ),
57 file_path: PathBuf::from( "/output/greeting.txt" ),
58 write_mode: WriteMode::Rewrite,
59 });
60
61 template.add_file( FileDescriptor
62 {
63 template_path: PathBuf::from( "/templates/config.hbs" ),
64 file_path: PathBuf::from( "/output/config.txt" ),
65 write_mode: WriteMode::Rewrite,
66 });
67
68 println!( "File descriptors added:" );
69 println!( " greeting.hbs -> greeting.txt" );
70 println!( " config.hbs -> config.txt" );
71 println!();
72
73 // Materialize (modifies the filesystem in place)
74 println!( "Materializing templates..." );
75 template.materialize()?;
76 println!( "✅ Materialization complete" );
77 println!();
78
79 // Access the filesystem via reference to read results
80 println!( "Generated files:" );
81 println!();
82
83 let greeting_content = template.filesystem().read( &PathBuf::from( "/output/greeting.txt" ) )?;
84 println!( "--- /output/greeting.txt ---" );
85 println!( "{greeting_content}" );
86 println!();
87
88 let config_content = template.filesystem().read( &PathBuf::from( "/output/config.txt" ) )?;
89 println!( "--- /output/config.txt ---" );
90 println!( "{config_content}" );
91 println!();
92
93 println!( "=== Advantages of Template API ===" );
94 println!();
95 println!( "• Generic over value types (V: TemplateValue)" );
96 println!( "• Generic over renderers (R: TemplateRenderer)" );
97 println!( "• Generic over filesystems (FS: FileSystem)" );
98 println!( "• Direct control over materialization process" );
99 println!( "• Useful for custom value types or renderers" );
100 println!();
101
102 println!( "=== When to use Template vs TemplateArchive ===" );
103 println!();
104 println!( "Use TemplateArchive when:" );
105 println!( " • You need serialization (JSON/YAML)" );
106 println!( " • You want self-contained archives" );
107 println!( " • You need parameter discovery and analysis" );
108 println!( " • Default Value type is sufficient" );
109 println!();
110 println!( "Use Template when:" );
111 println!( " • You need custom value types" );
112 println!( " • You need custom renderers" );
113 println!( " • You want fine-grained control" );
114 println!( " • Serialization is not needed" );
115 println!();
116
117 println!( "✅ Example completed successfully" );
118
119 Ok( () )
120}Sourcepub fn insert_value(&mut self, key: &str, value: V)
pub fn insert_value(&mut self, key: &str, value: V)
Inserts a value for template substitution.
§Parameters
key: Parameter namevalue: Value to substitute
§Examples
use genfile_core::{ Template, HandlebarsRenderer, MemoryFileSystem, Value };
let mut template: Template< Value, _, _ > = Template::new( HandlebarsRenderer::new(), MemoryFileSystem::new() );
template.insert_value( "name", Value::String( "test".into() ) );Examples found in repository?
20fn main() -> Result< (), Box< dyn core::error::Error > >
21{
22 println!( "=== Low-Level Template API Example ===" );
23 println!();
24
25 // Create renderer
26 let renderer = HandlebarsRenderer::new();
27
28 // Create two separate filesystems: one for templates, one for output
29 let mut template_fs = MemoryFileSystem::new();
30
31 // Prepare template files in the template filesystem
32 template_fs.write(
33 &PathBuf::from( "/templates/greeting.hbs" ),
34 "Hello, {{name}}!\n"
35 )?;
36
37 template_fs.write(
38 &PathBuf::from( "/templates/config.hbs" ),
39 "server={{server}}\nport={{port}}\n"
40 )?;
41
42 println!( "Template files prepared in memory filesystem" );
43 println!();
44
45 // Create template with explicit types using the template filesystem
46 let mut template = Template::< Value, _, _ >::new( renderer, template_fs );
47
48 // Insert values
49 template.insert_value( "name", Value::String( "World".into() ) );
50 template.insert_value( "server", Value::String( "localhost".into() ) );
51 template.insert_value( "port", Value::Number( 8080 ) );
52
53 // Add file descriptors
54 template.add_file( FileDescriptor
55 {
56 template_path: PathBuf::from( "/templates/greeting.hbs" ),
57 file_path: PathBuf::from( "/output/greeting.txt" ),
58 write_mode: WriteMode::Rewrite,
59 });
60
61 template.add_file( FileDescriptor
62 {
63 template_path: PathBuf::from( "/templates/config.hbs" ),
64 file_path: PathBuf::from( "/output/config.txt" ),
65 write_mode: WriteMode::Rewrite,
66 });
67
68 println!( "File descriptors added:" );
69 println!( " greeting.hbs -> greeting.txt" );
70 println!( " config.hbs -> config.txt" );
71 println!();
72
73 // Materialize (modifies the filesystem in place)
74 println!( "Materializing templates..." );
75 template.materialize()?;
76 println!( "✅ Materialization complete" );
77 println!();
78
79 // Access the filesystem via reference to read results
80 println!( "Generated files:" );
81 println!();
82
83 let greeting_content = template.filesystem().read( &PathBuf::from( "/output/greeting.txt" ) )?;
84 println!( "--- /output/greeting.txt ---" );
85 println!( "{greeting_content}" );
86 println!();
87
88 let config_content = template.filesystem().read( &PathBuf::from( "/output/config.txt" ) )?;
89 println!( "--- /output/config.txt ---" );
90 println!( "{config_content}" );
91 println!();
92
93 println!( "=== Advantages of Template API ===" );
94 println!();
95 println!( "• Generic over value types (V: TemplateValue)" );
96 println!( "• Generic over renderers (R: TemplateRenderer)" );
97 println!( "• Generic over filesystems (FS: FileSystem)" );
98 println!( "• Direct control over materialization process" );
99 println!( "• Useful for custom value types or renderers" );
100 println!();
101
102 println!( "=== When to use Template vs TemplateArchive ===" );
103 println!();
104 println!( "Use TemplateArchive when:" );
105 println!( " • You need serialization (JSON/YAML)" );
106 println!( " • You want self-contained archives" );
107 println!( " • You need parameter discovery and analysis" );
108 println!( " • Default Value type is sufficient" );
109 println!();
110 println!( "Use Template when:" );
111 println!( " • You need custom value types" );
112 println!( " • You need custom renderers" );
113 println!( " • You want fine-grained control" );
114 println!( " • Serialization is not needed" );
115 println!();
116
117 println!( "✅ Example completed successfully" );
118
119 Ok( () )
120}Sourcepub fn add_file(&mut self, descriptor: FileDescriptor)
pub fn add_file(&mut self, descriptor: FileDescriptor)
Adds a file descriptor specifying what file to generate.
§Parameters
descriptor: File descriptor with paths and write mode
§Examples
use genfile_core::{ Template, HandlebarsRenderer, MemoryFileSystem, Value, FileDescriptor, WriteMode };
use std::path::PathBuf;
let mut template: Template< Value, _, _ > = Template::new( HandlebarsRenderer::new(), MemoryFileSystem::new() );
template.add_file( FileDescriptor
{
file_path: PathBuf::from( "output.txt" ),
template_path: PathBuf::from( "template.hbs" ),
write_mode: WriteMode::Rewrite,
});Examples found in repository?
20fn main() -> Result< (), Box< dyn core::error::Error > >
21{
22 println!( "=== Low-Level Template API Example ===" );
23 println!();
24
25 // Create renderer
26 let renderer = HandlebarsRenderer::new();
27
28 // Create two separate filesystems: one for templates, one for output
29 let mut template_fs = MemoryFileSystem::new();
30
31 // Prepare template files in the template filesystem
32 template_fs.write(
33 &PathBuf::from( "/templates/greeting.hbs" ),
34 "Hello, {{name}}!\n"
35 )?;
36
37 template_fs.write(
38 &PathBuf::from( "/templates/config.hbs" ),
39 "server={{server}}\nport={{port}}\n"
40 )?;
41
42 println!( "Template files prepared in memory filesystem" );
43 println!();
44
45 // Create template with explicit types using the template filesystem
46 let mut template = Template::< Value, _, _ >::new( renderer, template_fs );
47
48 // Insert values
49 template.insert_value( "name", Value::String( "World".into() ) );
50 template.insert_value( "server", Value::String( "localhost".into() ) );
51 template.insert_value( "port", Value::Number( 8080 ) );
52
53 // Add file descriptors
54 template.add_file( FileDescriptor
55 {
56 template_path: PathBuf::from( "/templates/greeting.hbs" ),
57 file_path: PathBuf::from( "/output/greeting.txt" ),
58 write_mode: WriteMode::Rewrite,
59 });
60
61 template.add_file( FileDescriptor
62 {
63 template_path: PathBuf::from( "/templates/config.hbs" ),
64 file_path: PathBuf::from( "/output/config.txt" ),
65 write_mode: WriteMode::Rewrite,
66 });
67
68 println!( "File descriptors added:" );
69 println!( " greeting.hbs -> greeting.txt" );
70 println!( " config.hbs -> config.txt" );
71 println!();
72
73 // Materialize (modifies the filesystem in place)
74 println!( "Materializing templates..." );
75 template.materialize()?;
76 println!( "✅ Materialization complete" );
77 println!();
78
79 // Access the filesystem via reference to read results
80 println!( "Generated files:" );
81 println!();
82
83 let greeting_content = template.filesystem().read( &PathBuf::from( "/output/greeting.txt" ) )?;
84 println!( "--- /output/greeting.txt ---" );
85 println!( "{greeting_content}" );
86 println!();
87
88 let config_content = template.filesystem().read( &PathBuf::from( "/output/config.txt" ) )?;
89 println!( "--- /output/config.txt ---" );
90 println!( "{config_content}" );
91 println!();
92
93 println!( "=== Advantages of Template API ===" );
94 println!();
95 println!( "• Generic over value types (V: TemplateValue)" );
96 println!( "• Generic over renderers (R: TemplateRenderer)" );
97 println!( "• Generic over filesystems (FS: FileSystem)" );
98 println!( "• Direct control over materialization process" );
99 println!( "• Useful for custom value types or renderers" );
100 println!();
101
102 println!( "=== When to use Template vs TemplateArchive ===" );
103 println!();
104 println!( "Use TemplateArchive when:" );
105 println!( " • You need serialization (JSON/YAML)" );
106 println!( " • You want self-contained archives" );
107 println!( " • You need parameter discovery and analysis" );
108 println!( " • Default Value type is sufficient" );
109 println!();
110 println!( "Use Template when:" );
111 println!( " • You need custom value types" );
112 println!( " • You need custom renderers" );
113 println!( " • You want fine-grained control" );
114 println!( " • Serialization is not needed" );
115 println!();
116
117 println!( "✅ Example completed successfully" );
118
119 Ok( () )
120}Sourcepub fn materialize(&mut self) -> Result<(), Error>
pub fn materialize(&mut self) -> Result<(), Error>
Materializes all templates into files.
Reads each template, renders it with values, and writes to the target file using the appropriate write mode.
§Returns
Ok(()) on success, Error if any operation fails
§Errors
Returns error if:
- Template file can’t be read
- Template rendering fails
- Output file can’t be written
- TOML merging fails (for
TomlExtendmode)
§Examples
template.materialize()?;Examples found in repository?
20fn main() -> Result< (), Box< dyn core::error::Error > >
21{
22 println!( "=== Low-Level Template API Example ===" );
23 println!();
24
25 // Create renderer
26 let renderer = HandlebarsRenderer::new();
27
28 // Create two separate filesystems: one for templates, one for output
29 let mut template_fs = MemoryFileSystem::new();
30
31 // Prepare template files in the template filesystem
32 template_fs.write(
33 &PathBuf::from( "/templates/greeting.hbs" ),
34 "Hello, {{name}}!\n"
35 )?;
36
37 template_fs.write(
38 &PathBuf::from( "/templates/config.hbs" ),
39 "server={{server}}\nport={{port}}\n"
40 )?;
41
42 println!( "Template files prepared in memory filesystem" );
43 println!();
44
45 // Create template with explicit types using the template filesystem
46 let mut template = Template::< Value, _, _ >::new( renderer, template_fs );
47
48 // Insert values
49 template.insert_value( "name", Value::String( "World".into() ) );
50 template.insert_value( "server", Value::String( "localhost".into() ) );
51 template.insert_value( "port", Value::Number( 8080 ) );
52
53 // Add file descriptors
54 template.add_file( FileDescriptor
55 {
56 template_path: PathBuf::from( "/templates/greeting.hbs" ),
57 file_path: PathBuf::from( "/output/greeting.txt" ),
58 write_mode: WriteMode::Rewrite,
59 });
60
61 template.add_file( FileDescriptor
62 {
63 template_path: PathBuf::from( "/templates/config.hbs" ),
64 file_path: PathBuf::from( "/output/config.txt" ),
65 write_mode: WriteMode::Rewrite,
66 });
67
68 println!( "File descriptors added:" );
69 println!( " greeting.hbs -> greeting.txt" );
70 println!( " config.hbs -> config.txt" );
71 println!();
72
73 // Materialize (modifies the filesystem in place)
74 println!( "Materializing templates..." );
75 template.materialize()?;
76 println!( "✅ Materialization complete" );
77 println!();
78
79 // Access the filesystem via reference to read results
80 println!( "Generated files:" );
81 println!();
82
83 let greeting_content = template.filesystem().read( &PathBuf::from( "/output/greeting.txt" ) )?;
84 println!( "--- /output/greeting.txt ---" );
85 println!( "{greeting_content}" );
86 println!();
87
88 let config_content = template.filesystem().read( &PathBuf::from( "/output/config.txt" ) )?;
89 println!( "--- /output/config.txt ---" );
90 println!( "{config_content}" );
91 println!();
92
93 println!( "=== Advantages of Template API ===" );
94 println!();
95 println!( "• Generic over value types (V: TemplateValue)" );
96 println!( "• Generic over renderers (R: TemplateRenderer)" );
97 println!( "• Generic over filesystems (FS: FileSystem)" );
98 println!( "• Direct control over materialization process" );
99 println!( "• Useful for custom value types or renderers" );
100 println!();
101
102 println!( "=== When to use Template vs TemplateArchive ===" );
103 println!();
104 println!( "Use TemplateArchive when:" );
105 println!( " • You need serialization (JSON/YAML)" );
106 println!( " • You want self-contained archives" );
107 println!( " • You need parameter discovery and analysis" );
108 println!( " • Default Value type is sufficient" );
109 println!();
110 println!( "Use Template when:" );
111 println!( " • You need custom value types" );
112 println!( " • You need custom renderers" );
113 println!( " • You want fine-grained control" );
114 println!( " • Serialization is not needed" );
115 println!();
116
117 println!( "✅ Example completed successfully" );
118
119 Ok( () )
120}Sourcepub fn filesystem(&self) -> &FS
pub fn filesystem(&self) -> &FS
Returns a reference to the filesystem.
Useful for testing to verify generated files.
§Returns
Reference to the filesystem
Examples found in repository?
20fn main() -> Result< (), Box< dyn core::error::Error > >
21{
22 println!( "=== Low-Level Template API Example ===" );
23 println!();
24
25 // Create renderer
26 let renderer = HandlebarsRenderer::new();
27
28 // Create two separate filesystems: one for templates, one for output
29 let mut template_fs = MemoryFileSystem::new();
30
31 // Prepare template files in the template filesystem
32 template_fs.write(
33 &PathBuf::from( "/templates/greeting.hbs" ),
34 "Hello, {{name}}!\n"
35 )?;
36
37 template_fs.write(
38 &PathBuf::from( "/templates/config.hbs" ),
39 "server={{server}}\nport={{port}}\n"
40 )?;
41
42 println!( "Template files prepared in memory filesystem" );
43 println!();
44
45 // Create template with explicit types using the template filesystem
46 let mut template = Template::< Value, _, _ >::new( renderer, template_fs );
47
48 // Insert values
49 template.insert_value( "name", Value::String( "World".into() ) );
50 template.insert_value( "server", Value::String( "localhost".into() ) );
51 template.insert_value( "port", Value::Number( 8080 ) );
52
53 // Add file descriptors
54 template.add_file( FileDescriptor
55 {
56 template_path: PathBuf::from( "/templates/greeting.hbs" ),
57 file_path: PathBuf::from( "/output/greeting.txt" ),
58 write_mode: WriteMode::Rewrite,
59 });
60
61 template.add_file( FileDescriptor
62 {
63 template_path: PathBuf::from( "/templates/config.hbs" ),
64 file_path: PathBuf::from( "/output/config.txt" ),
65 write_mode: WriteMode::Rewrite,
66 });
67
68 println!( "File descriptors added:" );
69 println!( " greeting.hbs -> greeting.txt" );
70 println!( " config.hbs -> config.txt" );
71 println!();
72
73 // Materialize (modifies the filesystem in place)
74 println!( "Materializing templates..." );
75 template.materialize()?;
76 println!( "✅ Materialization complete" );
77 println!();
78
79 // Access the filesystem via reference to read results
80 println!( "Generated files:" );
81 println!();
82
83 let greeting_content = template.filesystem().read( &PathBuf::from( "/output/greeting.txt" ) )?;
84 println!( "--- /output/greeting.txt ---" );
85 println!( "{greeting_content}" );
86 println!();
87
88 let config_content = template.filesystem().read( &PathBuf::from( "/output/config.txt" ) )?;
89 println!( "--- /output/config.txt ---" );
90 println!( "{config_content}" );
91 println!();
92
93 println!( "=== Advantages of Template API ===" );
94 println!();
95 println!( "• Generic over value types (V: TemplateValue)" );
96 println!( "• Generic over renderers (R: TemplateRenderer)" );
97 println!( "• Generic over filesystems (FS: FileSystem)" );
98 println!( "• Direct control over materialization process" );
99 println!( "• Useful for custom value types or renderers" );
100 println!();
101
102 println!( "=== When to use Template vs TemplateArchive ===" );
103 println!();
104 println!( "Use TemplateArchive when:" );
105 println!( " • You need serialization (JSON/YAML)" );
106 println!( " • You want self-contained archives" );
107 println!( " • You need parameter discovery and analysis" );
108 println!( " • Default Value type is sufficient" );
109 println!();
110 println!( "Use Template when:" );
111 println!( " • You need custom value types" );
112 println!( " • You need custom renderers" );
113 println!( " • You want fine-grained control" );
114 println!( " • Serialization is not needed" );
115 println!();
116
117 println!( "✅ Example completed successfully" );
118
119 Ok( () )
120}