use genfile_core::
{
TemplateArchive,
FileRef,
InlineContent,
FileContent,
WriteMode,
Value,
HandlebarsRenderer,
MemoryFileSystem,
DefaultContentResolver,
FileSystem,
};
use std::path::PathBuf;
fn main() -> Result< (), Box< dyn core::error::Error > >
{
println!( "=== External Content Sources Example ===" );
println!();
let mut archive = TemplateArchive::new( "docs" );
archive.add_file_from(
PathBuf::from( "inline.txt" ),
InlineContent::new( FileContent::Text( "This is inline content".into() ) ),
WriteMode::Rewrite
);
archive.add_file_from(
PathBuf::from( "external_header.txt" ),
FileRef::new( PathBuf::from( "/templates/header.hbs" ) ),
WriteMode::Rewrite
);
archive.add_file_from(
PathBuf::from( "external_footer.txt" ),
FileRef::new( PathBuf::from( "/templates/footer.hbs" ) ),
WriteMode::Rewrite
);
println!( "Archive with mixed content sources:" );
println!( " Total files: {}", archive.file_count() );
println!();
println!( "=== Internalization (fetch and embed) ===" );
println!();
let mut mock_fs = MemoryFileSystem::new();
mock_fs.write(
&PathBuf::from( "/templates/header.hbs" ),
"=== {{title}} ===\n"
)?;
mock_fs.write(
&PathBuf::from( "/templates/footer.hbs" ),
"© {{year}} {{author}}\n"
)?;
let _resolver = DefaultContentResolver::new();
println!( "To internalize external content:" );
println!( " let resolver = CustomContentResolver::new();" );
println!( " archive.internalize( &resolver )?;" );
println!();
println!( "This fetches all external content and embeds it in the archive." );
println!();
println!( "=== Externalization (extract to files) ===" );
println!();
let mut inline_archive = TemplateArchive::new( "app" );
inline_archive.add_text_file(
PathBuf::from( "config.txt" ),
"app={{app_name}}\nversion={{version}}\n",
WriteMode::Rewrite
);
inline_archive.add_text_file(
PathBuf::from( "readme.txt" ),
"# {{app_name}}\n",
WriteMode::Rewrite
);
println!( "Archive before externalization:" );
println!( " Total files: {}", inline_archive.file_count() );
println!();
println!( "To externalize inline content:" );
println!( " let storage = CustomContentStorage::new();" );
println!( " archive.externalize( &storage, Path::new( \"/templates\" ) )?;" );
println!();
println!( "This extracts inline content to external files and updates references." );
println!();
println!( "=== Serialization ===" );
println!();
let json = archive.to_json_pretty()?;
println!( "JSON with external sources (first 600 chars):" );
let json_preview: String = json.chars().take( 600 ).collect();
println!( "{json_preview}" );
println!( "..." );
println!();
println!( "External file references are preserved in serialization." );
println!( "FileRef stores the path, not the content." );
println!();
println!( "=== Materialization ===" );
println!();
let mut demo_archive = TemplateArchive::new( "demo" );
demo_archive.add_text_file(
PathBuf::from( "output.txt" ),
"Title: {{title}}\nAuthor: {{author}}\nYear: {{year}}\n",
WriteMode::Rewrite
);
demo_archive.set_value( "title", Value::String( "External Content Guide".into() ) );
demo_archive.set_value( "author", Value::String( "genfile_core".into() ) );
demo_archive.set_value( "year", Value::Number( 2024 ) );
let renderer = HandlebarsRenderer::new();
let mut fs = MemoryFileSystem::new();
demo_archive.materialize_with_components(
PathBuf::from( "/output" ).as_path(),
&renderer,
&mut fs
)?;
let content = fs.read( &PathBuf::from( "/output/output.txt" ) )?;
println!( "Generated content:" );
println!( "{content}" );
println!();
println!( "✅ Example completed successfully" );
Ok( () )
}