Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 5 additions & 122 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "codegen"
description = "A tool to generate Rust source code from tera templates"
version = "0.1.1"
version = "0.2.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -15,7 +15,7 @@ globset = { version = "0.4", default-features = false }
rustfmt-wrapper = { version = "0.2" }
serde = { version = "1.0", default-features = false, features = ["std"] }
serde_json = { version = "1.0", default-features = false, features = ["std"] }
tera = { version = "1", default-features = false }
tera = { version = "2", default-features = false, features = ["glob_fs"] }

[dev-dependencies]
insta = "1"
Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ by `glam` users.

## Tera templates

Source files are generated using [`Tera`] templates. These kinds of templates
Source files are generated using [`Tera v2`] templates. These kinds of templates
are typically used to generate static web pages, but here we are using them to
generate Rust source. The main advantages are a lot of the template looks like
Rust code. The templates are fairly declarative and easier to follow than the
macros (in my opinion). I try to stick to basic features of the [templating
language] to keep things simple.

[`Tera`]: https://keats.github.io/tera/
[templating language]: https://keats.github.io/tera/docs/
[`Tera v2`]: https://keats.github.io/tera/
[templating language]: https://keats.github.io/tera/#template

### Control variables

Expand Down Expand Up @@ -77,7 +77,8 @@ Each template starts with setting up a number of common variables based on the
inputs from the `codegen` program. Commonly used variables are:

* `self_t` - the name of the type being generated
* `unsigned_scalar_t` - the unsigned version of `scalar_t` (e.g. `u8`, `u16`, `u32`)
* `unsigned_scalar_t` - the unsigned version of `scalar_t` (e.g. `u8`, `u16`,
`u32`)
* `inner_t` - the inner storage type used by this type (e.g. `__m128` or
`core::storage::XYZ<f32>`)
* `deref_t` - the type used by the `Deref` and `DerefMut` implementation - not
Expand All @@ -95,7 +96,8 @@ inputs from the `codegen` program. Commonly used variables are:

## Running `codegen`

The easiest way to run `codegen` on a clone of the glam repo is to first initialize the submodule with `git`:
The easiest way to run `codegen` on a clone of the glam repo is to first
initialize the submodule with `git`:

```sh
git submodule init
Expand All @@ -104,13 +106,13 @@ git submodule init
Then run it via `cargo`:

```sh
cargo run -p codegen
cargo run --release -p codegen
```

To pass additional parameters, e.g. `-h` for help:

```sh
cargo r -p codegen -- -h
cargo r --release -p codegen -- -h
```

`codegen` will generate all files by default or if a glob pattern is specified,
Expand Down Expand Up @@ -148,3 +150,4 @@ Licensed under either of
or [http://opensource.org/licenses/MIT])

at your option.

18 changes: 8 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use rustfmt_wrapper::rustfmt;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use tera::{from_value, to_value};

// use outputs::build_output_pairs;

Expand Down Expand Up @@ -53,11 +52,11 @@ impl Config {
context.insert("template_path", template_path);
for (prop_key, prop_value) in template.properties.iter() {
if let Some(prop_override) = output.properties.get(prop_key) {
context.insert(prop_key, prop_override);
context.insert(prop_key.clone(), prop_override);
} else {
// TODO: error message
if let Some(prop_value) = prop_value {
context.insert(prop_key, prop_value);
context.insert(prop_key.clone(), prop_value);
} else {
return Err(anyhow::Error::msg("Missing property override"));
}
Expand Down Expand Up @@ -235,14 +234,13 @@ fn main() -> anyhow::Result<()> {
let template_path = Path::new(config_root)
.join(&config.template_root)
.join("**/*.rs.tera");
let mut tera =
tera::Tera::new(template_path.to_str().unwrap()).context("tera parsing error(s)")?;
let mut tera = tera::Tera::new();
tera.load_from_glob(template_path.to_str().unwrap())
.context("tera parsing error(s)")?;
tera.register_filter(
"snake_case",
|value: &tera::Value, _: &_| -> tera::Result<tera::Value> {
let input = from_value::<String>(value.clone())?;
let mut iter = input.chars();

|value: &str, _: tera::Kwargs, _: &tera::State| -> String {
let mut iter = value.chars();
let mut string = String::new();

if let Some(first) = iter.next() {
Expand All @@ -255,7 +253,7 @@ fn main() -> anyhow::Result<()> {
string.push(char.to_ascii_lowercase());
}
}
tera::Result::Ok(to_value(string)?)
string
},
);

Expand Down