Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ description = "Generate Rust code for websocket API endpoints"
license = "MIT"

[package.metadata]
endpoint-libs-requirement = ">=1.0.3"
endpoint-libs-requirement = ">=1.1.1"

[dependencies]
# Internal dependencies
endpoint-libs = { git = "https://github.com/pathscale/endpoint-libs.git", tag = "v1.0.3" }
endpoint-libs = "1.1.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
eyre = "0.6"
Expand Down
33 changes: 33 additions & 0 deletions examples/minimal_project/config/roles.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#![enable(unwrap_newtypes)]
#![enable(unwrap_variant_newtypes)]
Config(
definition: EnumList (
[
Enum(
name: "UserRole",
variants: [
EnumVariant(
name: "Superadmin",
value: 1,
comment: "Superadmin can do literally everything. Very dangerous role.",
),
EnumVariant(
name: "Support",
value: 2,
comment: "Support can view and manage some staff.",
),
EnumVariant(
name: "Viewer",
value: 3,
comment: "Viewer can only view some data.",
),
EnumVariant(
name: "Regular",
value: 4,
comment: "Viewer can only view some data.",
),
],
),
]
)
)
12 changes: 11 additions & 1 deletion examples/minimal_project/config/s1_endpoints.ron
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetEvent1",
Expand Down Expand Up @@ -75,6 +76,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetDebugEvent1",
Expand All @@ -99,6 +101,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetOrder1",
Expand Down Expand Up @@ -129,6 +132,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetSignal1",
Expand Down Expand Up @@ -158,6 +162,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetBalance1",
Expand All @@ -175,6 +180,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetLivePosition1",
Expand Down Expand Up @@ -203,6 +209,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserSubLivePosition1",
Expand Down Expand Up @@ -245,6 +252,7 @@ Config(
)),
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserGetS1Ledger",
Expand Down Expand Up @@ -280,6 +288,7 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
EndpointSchema(
name: "UserCancelOrClosePosition1",
Expand All @@ -294,7 +303,8 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
]
)
)
)
3 changes: 2 additions & 1 deletion examples/minimal_project/config/test_schema.ron
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Config(
stream_response: None,
description: "",
json_schema: (),
roles: ["UserRole::Superadmin", "UserRole::Support"],
),
],
),
)
)
13 changes: 7 additions & 6 deletions src/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ pub fn gen_systemd_services(data: &Data, app_name: &str, user: &str) -> eyre::Re
for srv in &data.services {
let service_filename = data
.project_root
.join(format!("etc"))
.join(format!("systemd"))
.join("etc")
.join("systemd")
.join(format!("{}_{}.service", app_name, srv.name));
let mut service_file = File::create(&service_filename)?;
let v = get_systemd_service(app_name, &srv.name, user);
write!(&mut service_file, "{}", v)?;
write!(&mut service_file, "{v}")?;
}
Ok(())
}
Expand All @@ -92,25 +92,26 @@ pub fn get_error_messages(root: &Path) -> eyre::Result<ErrorMessages> {
}

if !def_filename.exists() {
let mut file = OpenOptions::new()
let _file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&def_filename)?;
}

// Read the file contents
let def_file = std::fs::read(&def_filename)?;

if def_file.is_empty() {
return Ok(ErrorMessages {
Ok(ErrorMessages {
language: String::from("TODO"),
codes: vec![ErrorMessage {
code: 0,
symbol: String::from("XXX"),
message: String::from("Please populate error_codes.json"),
source: String::from("None"),
}],
});
})
} else {
let definitions: ErrorMessages = serde_json::from_slice(&def_file)?;
Ok(definitions)
Expand Down
22 changes: 12 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ enum Definition {
EndpointSchemaList(String, u16, Vec<EndpointSchema>),
Enum(Type),
EnumList(Vec<Type>),
RoleList(Vec<Type>),
}

#[derive(Deserialize, Serialize)]
Expand All @@ -72,7 +73,7 @@ fn process_file(file_path: &Path) -> eyre::Result<Definition> {
let file_string = std::fs::read_to_string(file_path)?;
let config_file: Config = from_str(&file_string)?;

return Ok(config_file.definition);
Ok(config_file.definition)
}
_ => Err(eyre!(
"Non RON file OR file without extension in config dir "
Expand Down Expand Up @@ -128,17 +129,20 @@ fn build_object_lists(dir: PathBuf) -> eyre::Result<InputObjects> {
Definition::EndpointSchema(service_name, service_id, endpoint_schema) => {
service_schema_map
.entry((service_name, service_id))
.or_insert(vec![])
.or_default()
.push(endpoint_schema)
}
Definition::EndpointSchemaList(service_name, service_id, endpoint_schemas) => {
service_schema_map
.entry((service_name, service_id))
.or_insert(vec![])
.or_default()
.extend(endpoint_schemas)
}
Definition::Enum(enum_type) => enums.push(enum_type),
Definition::EnumList(enum_types) => enums.extend(enum_types),
Definition::RoleList(role_types) => {
enums.extend(role_types);
}
}
}

Expand Down Expand Up @@ -191,10 +195,8 @@ fn read_version_file(path: &Path) -> eyre::Result<VersionConfig> {
Ok(version_config)
}

fn check_compatibility(
version_config: VersionConfig
) -> eyre::Result<()> {
let current_crate_version = Version::parse(&get_crate_version()).unwrap();
fn check_compatibility(version_config: VersionConfig) -> eyre::Result<()> {
let current_crate_version = Version::parse(get_crate_version()).unwrap();

let binary_version_req = VersionReq::parse(&version_config.binary.version).unwrap();

Expand All @@ -206,8 +208,8 @@ fn check_compatibility(
let caller_libs_version = Version::parse(&version_config.libs.version).unwrap();

if !binary_version_req.matches(&current_crate_version) {
return Err(eyre!("Binary version constraint not satisfied. Version: {} is specified in version.toml. Current binary version is: {}",
&version_config.binary.version, &get_crate_version()));
Err(eyre!("Binary version constraint not satisfied. Version: {} is specified in version.toml. Current binary version is: {}",
&version_config.binary.version, &get_crate_version()))
} else if !libs_version_req.matches(&caller_libs_version) {
return Err(eyre!("endpoint-libs version constraint not satisfied. Version: {} is specified in version.toml. This version of endpoint-gen requires: {}",
caller_libs_version, libs_version_requirement));
Expand All @@ -234,7 +236,7 @@ fn main() -> Result<()> {

let config_dir = {
if let Some(config_dir) = &args.config_dir {
PathBuf::from_str(&config_dir)?
PathBuf::from_str(config_dir)?
} else {
env::current_dir()?
}
Expand Down
55 changes: 51 additions & 4 deletions src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use convert_case::{Case, Casing};
use endpoint_libs::model::{EnumVariant, Field, ProceduralFunction, Type};
use eyre::bail;
use itertools::Itertools;
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashMap};
use std::fs::File;
use std::io::Write;
use std::path::Path;
Expand All @@ -25,7 +25,7 @@ impl ToRust for Type {
Type::Struct { name, .. } => name.clone(),
Type::StructRef(name) => name.clone(),
Type::Object => "serde_json::Value".to_owned(),
Type::DataTable { name, .. } => format!("Vec<{}>", name),
Type::DataTable { name, .. } => format!("Vec<{name}>"),
Type::Vec(ele) => {
format!("Vec<{}>", ele.to_rust_ref(serde_with))
}
Expand Down Expand Up @@ -77,7 +77,7 @@ impl ToRust for Type {
if serde_with_opt.is_empty() {
"".to_string()
} else {
format!("#[serde(with = \"{}\")]", serde_with_opt)
format!("#[serde(with = \"{serde_with_opt}\")]")
},
x.name,
x.ty.to_rust_ref(serde_with)
Expand Down Expand Up @@ -285,12 +285,18 @@ impl From<EnumErrorCode> for ErrorCode {{

for s in &data.services {
for endpoint in &s.endpoints {
let roles_list = resolve_roles_ids(&endpoint.roles, &data.enums)
.into_iter()
.map(|x| x.to_string())
.join(", ");

write!(
&mut f,
"
impl WsRequest for {end_name2}Request {{
type Response = {end_name2}Response;
const METHOD_ID: u32 = {code};
const ROLES: &[u32] = &[{roles_list}];
const SCHEMA: &'static str = r#\"{schema}\"#;
}}
impl WsResponse for {end_name2}Response {{
Expand All @@ -310,6 +316,47 @@ impl WsResponse for {end_name2}Response {{
Ok(())
}

/// Resolves the IDs of roles from a list of role names and a list of enum types.
/// endpoint_roles: vec!["Role1::Value1", "Role1::Value2"]
fn resolve_roles_ids(endpoint_roles: &Vec<String>, all_enums: &Vec<Type>) -> Vec<i64> {
let mut all_enums_typed: HashMap<String, Vec<EnumVariant>> = HashMap::new();
for e in all_enums {
if let Type::Enum { name, variants } = e {
all_enums_typed.insert(name.clone(), variants.clone());
}
}

let mut roles_ids = vec![];
for role in endpoint_roles {
let (role_enum_name, role_variant_name) =
role.split_once("::").unwrap_or(("", role.as_str()));

if let Some(role_enum_variants) = all_enums_typed.get(role_enum_name) {
if let Some(role_variant_in_endpoint) = role_enum_variants
.iter()
.find(|v| v.name == role_variant_name)
{
roles_ids.push(role_variant_in_endpoint.value);
} else {
eprintln!(
"Warning: Role variant '{role_variant_name}' not found in enum '{role_enum_name}'"
);
}
} else {
eprintln!("Warning: Role enum '{role_enum_name}' not found");
}
}
// check there is not duplicate roles ids and print error if there are
let mut roles_ids_set: BTreeSet<i64> = BTreeSet::new();
for id in &roles_ids {
if !roles_ids_set.insert(*id) {
eprintln!("Warning: Duplicate role ID found: {id}");
}
}

roles_ids_set.into_iter().collect()
}

pub fn rustfmt(f: &Path) -> eyre::Result<()> {
let exit = Command::new("rustfmt")
.arg("--edition")
Expand Down Expand Up @@ -358,6 +405,6 @@ pub fn dump_endpoint_schema(data: &Data, mut writer: impl Write) -> eyre::Result
"#,
cases = cases.join("\n")
);
writeln!(writer, "{}", code)?;
writeln!(writer, "{code}")?;
Ok(())
}
5 changes: 1 addition & 4 deletions src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ StandardInput=null
[Install]
WantedBy=default.target

"#,
app_name = app_name,
service_name = service_name,
user = user
"#
)
}
Loading
Loading