Skip to content

Support for Manifest Serialization by Privileged Agent #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 9, 2024
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Read more in [The Pax Docs](https://docs.pax.dev/)

### Setup, macOS workstation

- Install `rustc` 1.70.0 via `rustup`
- Install `rustc` 1.75.0 via `rustup`
- Install the Pax CLI: `cargo install pax-cli`
- Follow instructions to build for [WebAssembly](#to-build-pax-projects-for-webassembly) or [macOS](#to-build-pax-projects-as-native-macos-apps) below
- Create a new project `pax-cli new my-first-project`
Expand Down
3 changes: 2 additions & 1 deletion pax-compiler/new-libdev-project-template/Cargo.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ default-run = "run"
pax-lang = { version="VERSION_PLACEHOLDER"}
pax-std = { version="VERSION_PLACEHOLDER"}
pax-compiler = {version = "VERSION_PLACEHOLDER", optional = true}
pax-manifest = {version = "VERSION_PLACEHOLDER", optional = true}
serde_json = {version = "1.0.95", optional = true}

[[bin]]
Expand All @@ -20,4 +21,4 @@ name = "run"
path = "bin/run.rs"

[features]
parser = ["pax-std/parser", "pax-lang/parser", "dep:serde_json", "dep:pax-compiler"]
parser = ["pax-std/parser", "pax-lang/parser", "dep:serde_json", "dep:pax-compiler", "dep:pax-manifest"]
30 changes: 16 additions & 14 deletions pax-compiler/src/building/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,22 @@ pub fn clone_all_to_pkg_dir(pax_dir: &PathBuf, pax_version: &Option<String>, ctx
if ctx.is_libdev_mode {
//Copy all packages from monorepo root on every build. this allows us to propagate changes
//to a libdev build without "sticky caches."
let pax_workspace_root = if let Ok(specified_override) = std::env::var("PAX_WORKSPACE_ROOT") {
PathBuf::from(&specified_override)
} else {
pax_dir
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap().into()
};

let pax_workspace_root =
if let Ok(specified_override) = std::env::var("PAX_WORKSPACE_ROOT") {
PathBuf::from(&specified_override)
} else {
pax_dir
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.into()
};

let src = pax_workspace_root.join(pkg);
let dest = dest_pkg_root.join(pkg);

Expand Down
200 changes: 100 additions & 100 deletions pax-compiler/src/cartridge_generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,69 +482,65 @@ fn recurse_generate_render_nodes_literal(
.map(|pd| {
let ril_literal_string = {
if let Some(merged_settings) = &tnd.settings {
if let Some(matched_setting) = merged_settings
.iter()
.find(|avd| {
match avd {
SettingElement::Setting(key, _) => key.token_value == pd.name,
_ => false
}
if let Some(matched_setting) =
merged_settings.iter().find(|avd| match avd {
SettingElement::Setting(key, _) => key.token_value == pd.name,
_ => false,
})
{
if let SettingElement::Setting(key, value) = matched_setting {
let setting_source_map_id =
source_map.insert(key.clone());
let setting_source_map_id = source_map.insert(key.clone());
let key_mapped_string = source_map.generate_mapped_string(
key.token_value.clone(),
setting_source_map_id,
);

match &value {
ValueDefinition::LiteralValue(lv) => {
let value_source_map_id = source_map.insert(lv.clone());
let value_mapped_string = source_map
.generate_mapped_string(
format!(
"Box::new(PropertyLiteral::new({}))",
lv.token_value
),
value_source_map_id,
);
Some((key_mapped_string.clone(), value_mapped_string))
}
ValueDefinition::Expression(t, id)
| ValueDefinition::Identifier(t, id) => {
let value_source_map_id = source_map.insert(t.clone());
let value_mapped_string = source_map
.generate_mapped_string(
format!(
match &value {
ValueDefinition::LiteralValue(lv) => {
let value_source_map_id = source_map.insert(lv.clone());
let value_mapped_string = source_map
.generate_mapped_string(
format!(
"Box::new(PropertyLiteral::new({}))",
lv.token_value
),
value_source_map_id,
);
Some((key_mapped_string.clone(), value_mapped_string))
}
ValueDefinition::Expression(t, id)
| ValueDefinition::Identifier(t, id) => {
let value_source_map_id = source_map.insert(t.clone());
let value_mapped_string = source_map
.generate_mapped_string(
format!(
"Box::new(PropertyExpression::new({}))",
id.expect("Tried to use expression but it wasn't compiled")),
value_source_map_id,
);
Some((key_mapped_string.clone(), value_mapped_string))
}
ValueDefinition::Block(block) => Some((
key_mapped_string.clone(),
MappedString::new(format!(
"Box::new(PropertyLiteral::new({}))",
recurse_literal_block(
block.clone(),
pd.get_type_definition(&rngc.type_table),
host_crate_info,
source_map
)
value_source_map_id,
);
Some((key_mapped_string.clone(), value_mapped_string))
}
ValueDefinition::Block(block) => Some((
key_mapped_string.clone(),
MappedString::new(format!(
"Box::new(PropertyLiteral::new({}))",
recurse_literal_block(
block.clone(),
pd.get_type_definition(&rngc.type_table),
host_crate_info,
source_map
)
)),
)),
)),
_ => {
panic!("Incorrect value bound to inline setting")
_ => {
panic!("Incorrect value bound to inline setting")
}
}
} else {
None
}
} else {
None
} }
else {
None
}
} else {
//no inline attributes at all; everything will be default
Expand Down Expand Up @@ -584,72 +580,76 @@ fn recurse_generate_render_nodes_literal(
.iter()
.map(|identifier_and_type| {
if let Some(inline_settings) = &tnd.settings {
if let Some(matched_setting) = inline_settings
.iter()
.find(|e|
{
if let SettingElement::Setting(key, _) = e {
key.token_value == *identifier_and_type.0
} else {
false
}
}
)
{
if let Some(matched_setting) = inline_settings.iter().find(|e| {
if let SettingElement::Setting(key, _) = e {
key.token_value == *identifier_and_type.0
} else {
false
}
}) {
if let SettingElement::Setting(key, value) = matched_setting {
let key_source_map_id = source_map.insert(key.clone());
let key_mapped_string = source_map.generate_mapped_string(key.token_value.clone(), key_source_map_id);
let key_source_map_id = source_map.insert(key.clone());
let key_mapped_string = source_map
.generate_mapped_string(key.token_value.clone(), key_source_map_id);

(
key_mapped_string,
match &value {
ValueDefinition::LiteralValue(lv) => {
let value_source_map_id = source_map.insert(lv.clone());
let mut literal_value = format!(
"Box::new(PropertyLiteral::new(Into::<{}>::into({})))",
identifier_and_type.1, lv.token_value,
);
if is_optional(&identifier_and_type.0) {
literal_value = format!("Some({})", literal_value);
}
let value_mapped_string = source_map
.generate_mapped_string(literal_value, value_source_map_id);
(
key_mapped_string,
match &value {
ValueDefinition::LiteralValue(lv) => {
let value_source_map_id = source_map.insert(lv.clone());
let mut literal_value = format!(
"Box::new(PropertyLiteral::new(Into::<{}>::into({})))",
identifier_and_type.1, lv.token_value,
);
if is_optional(&identifier_and_type.0) {
literal_value = format!("Some({})", literal_value);
}
let value_mapped_string = source_map
.generate_mapped_string(
literal_value,
value_source_map_id,
);

value_mapped_string
}
ValueDefinition::Expression(token, id)
| ValueDefinition::Identifier(token, id) => {
let value_source_map_id = source_map.insert(token.clone());
let mut literal_value = format!(
value_mapped_string
}
ValueDefinition::Expression(token, id)
| ValueDefinition::Identifier(token, id) => {
let value_source_map_id = source_map.insert(token.clone());
let mut literal_value =
format!(
"Box::new(PropertyExpression::new({}))",
id.expect("Tried to use expression but it wasn't compiled")
);
if is_optional(&identifier_and_type.0) {
literal_value = format!("Some({})", literal_value);
if is_optional(&identifier_and_type.0) {
literal_value = format!("Some({})", literal_value);
}
let value_mapped_string = source_map
.generate_mapped_string(
literal_value,
value_source_map_id,
);
value_mapped_string
}
let value_mapped_string = source_map
.generate_mapped_string(literal_value, value_source_map_id);
value_mapped_string
}
_ => {
panic!("Incorrect value bound to attribute")
}
},
)
_ => {
panic!("Incorrect value bound to attribute")
}
},
)
} else {
(
MappedString::new(identifier_and_type.0.to_string()),
MappedString::new(default_common_property_value(
&identifier_and_type.0,
)),
)
}
} else {
(
MappedString::new(identifier_and_type.0.to_string()),
MappedString::new(default_common_property_value(
&identifier_and_type.0,
)),
)
} } else {
(
MappedString::new(identifier_and_type.0.to_string()),
MappedString::new(default_common_property_value(
&identifier_and_type.0,
)),
)
}
} else {
(
Expand Down
61 changes: 58 additions & 3 deletions pax-compiler/src/code_serialization/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
use core::panic;
use std::{
fs::{self, File},
io::Write,
path::Path,
};

use syn::{parse_file, visit::Visit};
use tera::{Context, Tera};

use include_dir::{include_dir, Dir};
use pax_manifest::ComponentDefinition;

use crate::{
formatting::format_pax_template,
helpers::{replace_by_line_column, InlinedTemplateFinder},
};

#[allow(unused)]
static TEMPLATE_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/templates/code_serialization");
#[allow(unused)]
static MANIFEST_CODE_SERIALIZATION_TEMPLATE: &str = "manifest-code-serialization.tera";
#[allow(unused)]
static MACROS_TEMPLATE: &str = "macros.tera";

#[allow(unused)]
/// Serialize a component to a string
pub fn press_code_serialization_template(args: ComponentDefinition) -> String {
let mut tera = Tera::default();

Expand All @@ -36,6 +49,48 @@ pub fn press_code_serialization_template(args: ComponentDefinition) -> String {

let context = Context::from_serialize(args).unwrap();

tera.render(MANIFEST_CODE_SERIALIZATION_TEMPLATE, &context)
.expect("Failed to render template")
// Serialize component
let template = tera
.render(MANIFEST_CODE_SERIALIZATION_TEMPLATE, &context)
.expect("Failed to render template");

// Format component
format_pax_template(template).expect("Failed to format template")
}

/// Serialize a component to a file
/// Replaces entire .pax file and replaces inlined attribute directly for .rs files
pub fn serialize_component_to_file(component: &ComponentDefinition, file_path: String) {
let path = Path::new(&file_path);
let pascal_identifier = component.pascal_identifier.clone();
let serialized_component = press_code_serialization_template(component.clone());

match path.extension().and_then(|s| s.to_str()) {
Some("pax") => {
let mut file = File::create(file_path).expect("Failed to create file");
file.write_all(serialized_component.as_bytes())
.expect("Failed to write to file");
}
Some("rs") => write_inlined_pax(serialized_component, path, pascal_identifier),
_ => panic!("Unsupported file extension."),
}
}

fn write_inlined_pax(serialized_component: String, path: &Path, pascal_identifier: String) {
let content = fs::read_to_string(path).expect("Failed to read file");
let ast = parse_file(&content).expect("Failed to parse file");
let mut finder = InlinedTemplateFinder::new(content.clone());
finder.visit_file(&ast);

let template = finder
.templates
.iter()
.find(|t| t.struct_name == pascal_identifier);

if let Some(data) = template {
let new_template = format!("(\n{}\n)", serialized_component);
let modified_content =
replace_by_line_column(&content, data.start, data.end, new_template).unwrap();
fs::write(path, modified_content).expect("Failed to write to file");
}
}
Loading