Skip to main content

Template

Struct Template 

Source
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 implementing TemplateValue trait
  • R: Renderer implementing TemplateRenderer trait
  • FS: File system implementing FileSystem trait

§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>

Source

pub fn new(renderer: R, filesystem: FS) -> Self

Creates a new template with the given renderer and filesystem.

§Parameters
  • renderer: Template rendering engine
  • filesystem: 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?
examples/low_level_template.rs (line 46)
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}
Source

pub fn insert_value(&mut self, key: &str, value: V)

Inserts a value for template substitution.

§Parameters
  • key: Parameter name
  • value: 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?
examples/low_level_template.rs (line 49)
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}
Source

pub fn has_value(&self, key: &str) -> bool

Checks if a value exists for the given key.

§Parameters
  • key: Parameter name to check
§Returns

true if value exists, false otherwise

Source

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?
examples/low_level_template.rs (lines 54-59)
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}
Source

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 TomlExtend mode)
§Examples
template.materialize()?;
Examples found in repository?
examples/low_level_template.rs (line 75)
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}
Source

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?
examples/low_level_template.rs (line 83)
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}

Trait Implementations§

Source§

impl<V, R, FS> Debug for Template<V, R, FS>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<V, R, FS> Freeze for Template<V, R, FS>
where R: Freeze, FS: Freeze,

§

impl<V, R, FS> RefUnwindSafe for Template<V, R, FS>

§

impl<V, R, FS> Send for Template<V, R, FS>
where R: Send, FS: Send,

§

impl<V, R, FS> Sync for Template<V, R, FS>
where R: Sync, FS: Sync,

§

impl<V, R, FS> Unpin for Template<V, R, FS>
where R: Unpin, FS: Unpin, V: Unpin,

§

impl<V, R, FS> UnsafeUnpin for Template<V, R, FS>
where R: UnsafeUnpin, FS: UnsafeUnpin,

§

impl<V, R, FS> UnwindSafe for Template<V, R, FS>
where R: UnwindSafe, FS: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.