Crate genfile_core

Crate genfile_core 

Source
Expand description

§Module :: genfile

experimental rust-status docs.rs discord

A trait-based template processing and file generation library for Rust. genfile provides self-contained template archives with parameter storage, pluggable rendering engines, and testable in-memory file systems.

§Features

  • Self-Contained Archives: Template files with embedded parameters stored inside (JSON/YAML serialization)
  • Binary + Text Support: Handle both text templates and binary files (images, etc.) with base64 encoding
  • Pluggable Architecture: Trait-based design for custom value types, renderers, and file systems
  • Testable: Built-in MemoryFileSystem for fast, isolated testing without disk I/O
  • Security: Path traversal validation prevents directory escape attacks
  • External Content: Support for FileRef and UrlRef with custom resolvers and storage backends
  • Template Engine: Default Handlebars renderer with support for custom engines
  • 215 Tests: Comprehensive test coverage including 27 security tests

§Quick Start

Add to your Cargo.toml:

[dependencies]
genfile_core = "0.1"

§Basic Example

use genfile_core::{ TemplateArchive, WriteMode, Value, MemoryFileSystem, HandlebarsRenderer, FileSystem };
use std::path::{ Path, PathBuf };

// Create a template archive
let mut archive = TemplateArchive::new( "my-project" );

// Add template files
archive.add_text_file(
  PathBuf::from( "README.md" ),
  "# {{project_name}}\n\n{{description}}",
  WriteMode::Rewrite
);

archive.add_text_file(
  PathBuf::from( "src/main.rs" ),
  "fn main() {\n  println!(\"Hello from {{project_name}}!\");\n}",
  WriteMode::Rewrite
);

// Set parameter values
archive.set_value( "project_name", Value::String( "MyApp".into() ) );
archive.set_value( "description", Value::String( "A cool application".into() ) );

// Materialize to memory filesystem (for testing)
let renderer = HandlebarsRenderer::new();
let mut fs = MemoryFileSystem::new();

archive.materialize_with_components(
  Path::new( "/output" ),
  &renderer,
  &mut fs
).unwrap();

// Verify generated files
assert!( fs.exists( &PathBuf::from( "/output/README.md" ) ) );
assert_eq!(
  fs.read( &PathBuf::from( "/output/README.md" ) ).unwrap(),
  "# MyApp\n\nA cool application"
);

§Sample

§Examples

§Archive with Binary Files

use genfile_core::{ TemplateArchive, FileContent, WriteMode, Value };
use std::path::PathBuf;

let mut archive = TemplateArchive::new( "website" );

// Text template
archive.add_text_file(
  PathBuf::from( "index.html" ),
  "<html><title>{{title}}</title></html>",
  WriteMode::Rewrite
);

// Binary file (PNG header)
archive.add_binary_file(
  PathBuf::from( "logo.png" ),
  vec![ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ]
);

archive.set_value( "title", Value::String( "My Site".into() ) );

§Serialization and Persistence

use genfile_core::TemplateArchive;

// Create and serialize to JSON
let archive = TemplateArchive::new( "config" );
let json = archive.to_json_pretty().unwrap();

// Save to file
std::fs::write( "template.json", json ).unwrap();

// Load from file
let json = std::fs::read_to_string( "template.json" ).unwrap();
let restored = TemplateArchive::from_json( &json ).unwrap();

§External Content Sources

use genfile_core::{ TemplateArchive, FileRef, UrlRef, WriteMode };
use std::path::PathBuf;

let mut archive = TemplateArchive::new( "docs" );

// Reference external file
archive.add_file_from(
  PathBuf::from( "header.txt" ),
  FileRef::new( PathBuf::from( "/templates/header.hbs" ) ),
  WriteMode::Rewrite
);

// Reference URL
archive.add_file_from(
  PathBuf::from( "footer.txt" ),
  UrlRef::new( "https://example.com/templates/footer.hbs" ),
  WriteMode::Rewrite
);

§Custom Storage Backend

use genfile_core::{ TemplateArchive, ContentStorage, FileContent, HandlebarsRenderer };
use std::path::Path;

struct CloudStorage;

impl ContentStorage for CloudStorage
{
  fn store( &mut self, path: &Path, content: &FileContent ) -> Result< (), genfile_core::Error >
  {
    // Upload to S3, Azure, etc.
    println!( "Uploading {} to cloud", path.display() );
    Ok( () )
  }
}

§Parameter Discovery and Analysis

use genfile_core::{ TemplateArchive, ParameterDescriptor, WriteMode };
use std::path::PathBuf;

let mut archive = TemplateArchive::new( "app" );
archive.add_text_file(
  PathBuf::from( "config.txt" ),
  "App: {{app_name}}",
  WriteMode::Rewrite
);

// Add parameter definitions
archive.add_parameter( ParameterDescriptor
{
  parameter: "app_name".into(),
  is_mandatory: true,
  default_value: None,
  description: Some( "Application name".into() ),
});

// Discover parameters used in templates
let discovered = archive.discover_parameters();

// Analyze parameter usage
let usage = archive.analyze_parameter_usage();

// Find undefined parameters
let undefined = archive.get_undefined_parameters();

§API Overview

§Core Types

  • TemplateArchive - Main entity for template operations, stores files, parameters, and values
  • Template<V,R> - Alternative API with custom value types and renderers
  • TemplateFile - Individual file with content, metadata, and optional external source
  • FileContent - Enum for Text(String) or Binary(Vec<u8>)
  • Value - Default parameter value type: String, Number, Bool, List

§Traits

  • TemplateValue - Trait for custom parameter value types
  • TemplateRenderer - Trait for pluggable rendering engines (default: Handlebars)
  • FileSystem - Trait for file operations (RealFileSystem or MemoryFileSystem)
  • ContentResolver - Trait for resolving external content sources
  • ContentStorage - Trait for custom storage backends

§Content Sources

  • ContentSource::Inline - Content embedded directly in archive
  • ContentSource::File - Reference to external file path
  • ContentSource::Url - Reference to remote URL

§Security

All file paths are validated to prevent directory traversal attacks:

use genfile_core::validate_path;
use std::path::Path;

// Valid paths
assert!( validate_path( Path::new( "src/lib.rs" ) ).is_ok() );
assert!( validate_path( Path::new( "./foo/bar.txt" ) ).is_ok() );

// Invalid paths (rejected)
assert!( validate_path( Path::new( "../etc/passwd" ) ).is_err() );
assert!( validate_path( Path::new( "foo/../../bar" ) ).is_err() );

27 dedicated security tests ensure protection against malicious paths.

§Testing

Use MemoryFileSystem for fast, isolated tests:

use genfile_core::{ TemplateArchive, MemoryFileSystem, HandlebarsRenderer, FileSystem };
use std::path::Path;

#[ test ]
fn test_generation()
{
  let archive = TemplateArchive::new( "test" );
  let renderer = HandlebarsRenderer::new();
  let mut fs = MemoryFileSystem::new();

  // No disk I/O - runs in memory
  archive.materialize_with_components(
    Path::new( "/output" ),
    &renderer,
    &mut fs
  ).unwrap();

  // Fast assertions
  assert!( fs.exists( Path::new( "/output/README.md" ) ) );
}

File generation tools for code generation and template materialization.

genfile_core provides a trait-based template processing and file generation library that supports custom value types, pluggable rendering engines, and testable in-memory file systems.

§Architecture

The library is organized around two main APIs:

  1. TemplateArchive - Self-contained archive with files, parameters, and values

    • Recommended for most use cases
    • Supports JSON/YAML serialization
    • Parameter definitions and values stored inside the archive
    • External content sources with internalize/externalize operations
  2. Template - Lower-level template processor

    • Generic over value types and renderers
    • Direct filesystem and renderer control
    • Useful when you need custom value types or renderers

§Core Concepts

§Values and Parameters

  • TemplateValue - Trait for custom value types
  • Value - Default value enum (String, Number, Bool, List)
  • ParameterDescriptor - Parameter metadata (name, mandatory, default, description)
  • Values - Runtime storage for parameter values

§Rendering

§File System

§Content Sources

§Module Organization

The crate is organized into focused modules:

§See Also

Re-exports§

pub use value::TemplateValue;
pub use value::Value;
pub use parameter::ParameterDescriptor;
pub use parameter::Parameters;
pub use values::Values;
pub use error::Error;
pub use security::validate_path;
pub use renderer::TemplateRenderer;
pub use renderer::HandlebarsRenderer;
pub use file_descriptor::FileDescriptor;
pub use file_descriptor::WriteMode;
pub use filesystem::FileSystem;
pub use filesystem::MemoryFileSystem;
pub use filesystem::RealFileSystem;
pub use template::Template;
pub use archive::TemplateArchive;
pub use archive::TemplateFile;
pub use archive::FileContent;
pub use archive::FileMetadata;
pub use archive::ArchiveMetadata;
pub use archive::MaterializationReport;
pub use content_source::ContentSource;
pub use content_source::IntoContentSource;
pub use content_source::FileRef;
pub use content_source::UrlRef;
pub use content_source::InlineContent;
pub use content_source::ContentResolver;
pub use content_source::ContentStorage;
pub use content_source::DefaultContentResolver;
pub use content_source::DefaultContentStorage;

Modules§

archive
Self-contained template archives with serialization support.
content_source
Content source abstractions for external data references.
error
Error types for genfile operations.
file_descriptor
File descriptors and write modes for template materialization.
filesystem
File system abstractions for testability.
parameter
Parameter descriptors and collections.
prelude
Prelude for convenient imports.
renderer
Template rendering engines and the TemplateRenderer trait.
security
Security validation functions for path traversal prevention.
template
Low-level template processor with custom value types and renderers.
value
Template value types and the TemplateValue trait.
values
Runtime value storage for template substitution.