123 lines
3.6 KiB
V
123 lines
3.6 KiB
V
module embedfs
|
|
|
|
import os
|
|
import strings
|
|
import net.http.mime
|
|
|
|
pub struct CodeGenerator {
|
|
pub:
|
|
// Path to file or directory to embed
|
|
path string @[required]
|
|
// Path prefix if you want to add extra prefix for file paths
|
|
prefix string
|
|
// Glob patterns to match files the must be ignored when generating the code
|
|
ignore_patterns []string
|
|
// If true set the default MIME-type for files if no MIME-type detected
|
|
force_mimetype bool
|
|
// Default MIME-type for files. See https://www.iana.org/assignments/media-types/media-types.xhtml
|
|
default_mimetype string = 'application/octet-stream'
|
|
// Name of generated module
|
|
module_name string = 'main'
|
|
// Name of constant which will contain embedded files
|
|
const_name string = 'embedfs'
|
|
// If true make constant public
|
|
make_const_pub bool
|
|
// If true make all symbols in generated module public
|
|
make_pub bool
|
|
// Generate map[string]EmbedFile instead of EmbedFileSystem instance
|
|
bare_map bool
|
|
}
|
|
|
|
struct EmbedFileSpec {
|
|
key string
|
|
path string
|
|
name string
|
|
ext string
|
|
mimetype string
|
|
}
|
|
|
|
pub fn (g CodeGenerator) generate() string {
|
|
visible := if g.make_pub == true { 'pub ' } else { '' }
|
|
const_visible := if g.make_pub == true || g.make_const_pub == true { 'pub ' } else { '' }
|
|
mut b := strings.new_builder(1024 * 4)
|
|
b.writeln('// !WARNING! This file is generated by embedfs module, do not edit it.')
|
|
b.writeln('')
|
|
b.writeln('module ${g.module_name}')
|
|
b.writeln('')
|
|
b.writeln('import v.embed_file { EmbedFileData }')
|
|
b.writeln('')
|
|
b.writeln('${visible}struct EmbedFileMetadata {')
|
|
b.writeln('\tkey string')
|
|
b.writeln('\tname string')
|
|
b.writeln('\text string')
|
|
b.writeln('\tmimetype string')
|
|
b.writeln('}')
|
|
b.writeln('')
|
|
b.writeln('${visible}struct EmbedFile {')
|
|
b.writeln('\tdata EmbedFileData')
|
|
b.writeln('\tmeta EmbedFileMetadata')
|
|
b.writeln('}')
|
|
b.writeln('')
|
|
b.writeln('${visible}struct EmbedFileSystem {')
|
|
b.writeln('\tfiles map[string]EmbedFile')
|
|
b.writeln('}')
|
|
b.writeln('')
|
|
if g.bare_map {
|
|
b.writeln('${const_visible}const ${g.const_name} = {')
|
|
g.write_embed_file_map_item(mut b)
|
|
b.writeln('}')
|
|
} else {
|
|
b.writeln('${const_visible}const ${g.const_name} = EmbedFileSystem{')
|
|
b.writeln('\tfiles: {')
|
|
g.write_embed_file_map_item(mut b)
|
|
b.writeln('\t}')
|
|
b.writeln('}')
|
|
}
|
|
return b.str()
|
|
}
|
|
|
|
fn (g CodeGenerator) get_files() []EmbedFileSpec {
|
|
mut file_list := &[]string{}
|
|
os.walk(g.path, fn [mut file_list] (file string) {
|
|
file_list << file
|
|
})
|
|
mut files := []EmbedFileSpec{}
|
|
outer: for file in file_list {
|
|
for glob in g.ignore_patterns {
|
|
if file.match_glob(glob) {
|
|
continue outer
|
|
}
|
|
}
|
|
file_key := os.join_path_single(g.prefix, file)
|
|
file_path := file // the actual path used in $embed_file() statement
|
|
file_name := os.file_name(file_path)
|
|
file_ext := os.file_ext(file_name).replace_once('.', '')
|
|
mut mimetype := mime.get_mime_type(file_ext)
|
|
if g.force_mimetype && mimetype == '' {
|
|
mimetype = g.default_mimetype
|
|
}
|
|
files << EmbedFileSpec{
|
|
key: file_key
|
|
path: file_path
|
|
name: file_name
|
|
ext: file_ext
|
|
mimetype: mimetype
|
|
}
|
|
}
|
|
return files
|
|
}
|
|
|
|
fn (g CodeGenerator) write_embed_file_map_item(mut b strings.Builder) {
|
|
for filespec in g.get_files() {
|
|
b.writeln("\t\t'${filespec.key}': EmbedFile{")
|
|
b.writeln("\t\t\tdata: \$embed_file('${filespec.path}')")
|
|
b.writeln('\t\t\tmeta: EmbedFileMetadata{')
|
|
b.writeln("\t\t\t\tkey: '${filespec.key}'")
|
|
b.writeln("\t\t\t\tname: '${filespec.name}'")
|
|
b.writeln("\t\t\t\text: '${filespec.ext}'")
|
|
b.writeln("\t\t\t\tmimetype: '${filespec.mimetype}'")
|
|
b.writeln('\t\t\t}')
|
|
b.writeln('\t\t},')
|
|
}
|
|
}
|