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
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.2"

[dependencies]
# Internal dependencies
endpoint-libs = { git = "https://github.com/pathscale/endpoint-libs.git", tag = "v1.0.3" }
endpoint-libs = "1.1.2"
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