use zerodds_ast::Ast;
use zerodds_lang_rules::adapter::interface::{
InterfaceError, Service, all_operations_flattened, in_struct_name, out_struct_name, services,
};
use zerodds_soap::wsdl::Operation;
pub fn operations_of(ast: &Ast) -> Result<Vec<(Service, Vec<Operation>)>, InterfaceError> {
let mut out = Vec::new();
for service in services(ast)? {
let flattened = all_operations_flattened(ast, service.id)?;
let mut ops = Vec::with_capacity(flattened.len());
for op in &flattened {
ops.push(Operation {
name: op.name.clone(),
input_type: in_struct_name(&service.name, &op.name),
output_type: out_struct_name(&service.name, &op.name),
});
}
out.push((service, ops));
}
Ok(out)
}
#[must_use]
pub fn builtin_operations() -> Vec<Operation> {
let pairs: &[&str] = &[
"CreateApplication",
"DeleteApplication",
"GetApplications",
"CreateParticipant",
"UpdateParticipant",
"DeleteParticipant",
"GetParticipants",
"CreateTopic",
"UpdateTopic",
"DeleteTopic",
"GetTopics",
"CreatePublisher",
"UpdatePublisher",
"DeletePublisher",
"GetPublishers",
"CreateSubscriber",
"UpdateSubscriber",
"DeleteSubscriber",
"GetSubscribers",
"CreateDataWriter",
"UpdateDataWriter",
"DeleteDataWriter",
"GetDataWriters",
"CreateDataReader",
"UpdateDataReader",
"DeleteDataReader",
"GetDataReaders",
"WriteSample",
"ReadSample",
"CreateWaitset",
"UpdateWaitset",
"GetWaitset",
"DeleteWaitset",
"GetWaitsets",
];
pairs
.iter()
.map(|name| Operation {
name: (*name).to_string(),
input_type: format!("{name}Request"),
output_type: format!("{name}Response"),
})
.collect()
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn interface_operations_become_wsdl_operations() {
let ast = zerodds_wire_probe::encode::model_from_idl(
"interface Calculator { long add(in long a, in long b); };",
"t.idl",
)
.expect("parses");
let all = operations_of(&ast).expect("ok");
assert_eq!(all.len(), 1);
let (service, ops) = &all[0];
assert_eq!(service.name, "Calculator");
assert_eq!(ops.len(), 1);
assert_eq!(ops[0].name, "add");
assert!(ops[0].input_type.contains("Calculator"));
assert!(ops[0].output_type.contains("Calculator"));
}
#[test]
fn builtin_operations_cover_the_object_model() {
let ops = builtin_operations();
assert!(ops.iter().any(|o| o.name == "WriteSample"));
assert!(ops.iter().any(|o| o.name == "ReadSample"));
assert!(ops.iter().any(|o| o.name == "CreateApplication"));
assert!(ops.iter().any(|o| o.name == "UpdateTopic"));
assert_eq!(ops.len(), 34);
}
#[test]
fn interfaces_with_attributes_get_implied_operations() {
let ast = zerodds_wire_probe::encode::model_from_idl(
"interface Counter { attribute long value; };",
"t.idl",
)
.expect("parses");
let all = operations_of(&ast).expect("ok");
let (_, ops) = &all[0];
assert_eq!(ops.len(), 2);
}
}