{# ei-scanner jinja template, for `` #}
#![allow(unused_parens, clippy::useless_conversion, clippy::double_parens, clippy::match_single_binding)]
// GENERATED FILE
{# TODO handle destructor #}
{# TODO handle context_type #}
{% macro interface_type(interface) -%}
super::{{interface.plainname}}::{{interface.plainname|camel}}
{%- endmacro %}
{% macro arg_type(arg, owned, generic) -%}
{% if arg.enum != None %} {{ arg.enum.name|camel }}
{% elif arg.protocol_type == 'string' and owned %} String
{% elif arg.protocol_type == 'string' %} &str
{% elif arg.protocol_type == 'int32' %} i32
{% elif arg.protocol_type == 'uint32' %} u32
{% elif arg.protocol_type == 'int64' %} i64
{% elif arg.protocol_type == 'uint64' %} u64
{% elif arg.protocol_type == 'object' and owned %} {{interface_type(arg.interface)}}
{% elif arg.protocol_type == 'object' %} &{{interface_type(arg.interface)}}
{% elif arg.protocol_type == 'new_id' and arg.interface %} {{interface_type(arg.interface)}}
{% elif arg.protocol_type == 'new_id' and arg.interface_arg and generic %} {{arg.interface_arg.name|camel}}
{% elif arg.protocol_type == 'new_id' and arg.interface_arg %} crate::Object
{% elif arg.protocol_type == 'float' %} f32
{% elif arg.protocol_type == 'fd' and owned %} std::os::unix::io::OwnedFd
{% elif arg.protocol_type == 'fd' %} std::os::unix::io::BorrowedFd
{% else %} unhandled_arg_type_{{arg.protocol_type}}
{% endif %}
{%- endmacro %}
{% macro return_type(arguments) -%}
{%- endmacro %}
{% macro incoming_enum() -%}
{% if extra.eis %}
Request
{% else %}
Event
{% endif %}
{%- endmacro %}
{% macro module() -%}
{% if extra.eis %}
crate::eis
{% else %}
crate::ei
{% endif %}
{%- endmacro %}
{% for interface in interfaces %}
/** {{interface.description.text|ei_escape_names}} */
pub mod {{interface.plainname}} {
#[derive(Clone, Debug)]
pub struct {{interface.plainname|camel}}(pub(crate) crate::Object);
impl crate::private::Sealed for {{interface.plainname|camel}} {}
impl crate::Interface for {{interface.plainname|camel}} {
const NAME: &'static str = "{{interface.protocol_name}}";
const VERSION: u32 = {{interface.version}};
{% if extra.eis %}
const CLIENT_SIDE: bool = false;
{% else %}
const CLIENT_SIDE: bool = true;
{% endif %}
type Incoming = {{incoming_enum()}};
fn new_unchecked(object: crate::Object) -> Self {
Self(object)
}
fn as_arg(&self) -> crate::Arg<'_> {
self.0.as_arg()
}
}
impl {{module()}}::Interface for {{interface.plainname|camel}} {}
impl {{interface.plainname|camel}} {
{% for outgoing in interface.outgoing %}
/** {{outgoing.description.text|ei_escape_names}} */
pub fn {{outgoing.name}}<
{%- for arg in outgoing.arguments %}
{% if arg.interface_arg_for %}
{{arg.name|camel}}: {{module()}}::Interface
{% endif %}
{% endfor -%}
>(
&self,
{%- for arg in outgoing.arguments %}
{% if arg.protocol_type != 'new_id' and not arg.interface_arg_for %}
{{arg.name}}: {{arg_type(arg, false, false)}},
{% endif %}
{% endfor -%}
) -> (
{%- for arg in outgoing.arguments %}
{% if arg.protocol_type == 'new_id' %}
{{arg_type(arg, true, true)}}
{% endif %}
{% endfor -%}
) {
{%- for arg in outgoing.arguments %}
{% if arg.protocol_type == 'new_id' and arg.interface_arg %}
let {{arg.name}} = self.0.backend().new_id({{arg.interface_arg.name|camel}}::NAME.to_string(), {{arg.version_arg.name}});
{% elif arg.protocol_type == 'new_id' %}
let {{arg.name}} = self.0.backend().new_id("{{arg.interface.protocol_name}}".to_string(), {{arg.version_arg.name}});
{% endif -%}
{% endfor -%}
let args = &[
{%- for arg in outgoing.arguments %}
{% if arg.interface_arg_for %}
crate::Arg::{{arg.protocol_type|camel}}({{arg.name|camel}}::NAME),
{% else %}
crate::Arg::{{arg.protocol_type|camel}}({{arg.name}}.into()),
{% endif %}
{% endfor -%}
];
self.0.request({{outgoing.opcode}}, args);
{% if outgoing.is_destructor %}
self.0.backend().remove_id(self.0.id());
{% endif %}
(
{%- for arg in outgoing.arguments %}
{% if arg.protocol_type == 'new_id' %}
{% if arg.interface %}
{{arg_type(arg, true, false)}}(crate::Object::new(
self.0.backend().clone(), {{arg.name}},
{% if extra.eis %}
false
{% else %}
true
{% endif %}
))
{% elif arg.interface_arg %}
crate::Object::new(self.0.backend().clone(), {{arg.name}},
{% if extra.eis %}
false
{% else %}
true
{% endif %}
).downcast_unchecked()
{% else -%}
unreachable
{% endif -%}
{% endif -%}
{% endfor -%}
)
}
{% endfor %}
}
{% for enum in interface.enums %}
/** {{enum.description.text|ei_escape_names}} */
#[derive(Clone, Copy, Debug)]
pub enum {{enum.camel_name}} {
{% for entry in enum.entries %}
/** {{entry.summary}} */
{{entry.name|camel}} = {{entry.value}},
{% endfor %}
}
impl From<{{enum.camel_name}}> for u32 {
fn from(value: {{enum.camel_name}}) -> u32 {
value as u32
}
}
impl crate::OwnedArg for {{enum.camel_name}} {
fn parse(buf: &mut crate::ByteStream) -> Result<Self, crate::ParseError> {
match u32::parse(buf)? {
{% for entry in enum.entries %}
{{entry.value}} => Ok(Self::{{entry.name|camel}}),
{% endfor %}
variant => Err(crate::ParseError::InvalidVariant("{{enum.camel_name}}", variant)),
}
}
fn as_arg(&self) -> crate::Arg<'_> {
crate::Arg::Uint32(*self as u32)
}
fn enum_name(&self) -> Option<(&'static str, &'static str)> {
Some(("{{enum.name}}", match self {
{% for entry in enum.entries %}
Self::{{entry.name|camel}} => "{{entry.name}}",
{% endfor %}
}
))
}
}
{% endfor %}
#[non_exhaustive]
#[derive(Debug)]
pub enum {{incoming_enum()}} {
{% for incoming in interface.incoming %}
/** {{incoming.description.text|ei_escape_names}} */
{{ incoming.name|camel }}
{% if incoming.arguments %}
{ {% for arg in incoming.arguments %}
{% if not (arg.version_arg_for or arg.interface_arg_for) %}
/** {{arg.summary}} */
{{arg.name}}: {{arg_type(arg, true, false)}},
{% endif %}
{% endfor %} }
{% endif %},
{% endfor %}
}
impl {{incoming_enum()}} {
pub(super) fn op_name(operand: u32) -> Option<&'static str> {
match operand {
{% for incoming in interface.incoming %}
{{incoming.opcode}} => Some("{{incoming.name}}"),
{% endfor %}
_ => None
}
}
pub(super) fn parse(operand: u32, _bytes: &mut crate::ByteStream) -> Result<Self, crate::ParseError> {
match operand {
{% for incoming in interface.incoming %}
{{incoming.opcode}} => {
{% for arg in incoming.arguments %}
let {{arg.name}} = _bytes.read_arg()?;
{% endfor %}
Ok(Self::{{ incoming.name|camel }}
{% if incoming.arguments %} {
{% for arg in incoming.arguments %}
{% if arg.version_arg_for or arg.interface_arg_for %}
{% elif arg.protocol_type == 'new_id' and arg.interface_arg %}
{{arg.name}}: _bytes.backend().new_peer_object({{arg.name}}, {{arg.interface_arg.name}}, {{arg.version_arg.name}})?,
{% elif arg.protocol_type == 'new_id' %}
{{arg.name}}: _bytes.backend().new_peer_interface({{arg.name}}, {{arg.version_arg.name}})?,
{% else %}
{{arg.name}},
{% endif %}
{% endfor %} }
{% endif %} )
}
{% endfor %}
opcode => Err(crate::ParseError::InvalidOpcode("{{interface.plainname}}", opcode)),
}
}
#[allow(unused_imports, unused_mut, unused_variables, unreachable_code, unreachable_patterns)]
pub(super) fn args(&self) -> Vec<crate::Arg<'_>> {
use crate::{arg::OwnedArg, Interface};
let mut args = Vec::new();
match self {
{% for incoming in interface.incoming %}
{% if incoming.arguments %}
Self::{{ incoming.name|camel }} {
{% for arg in incoming.arguments %}
{% if not (arg.version_arg_for or arg.interface_arg_for) %}
{{arg.name}},
{% endif %}
{% endfor %}
} => {
{% for arg in incoming.arguments %}
{% if not (arg.version_arg_for or arg.interface_arg_for) %}
args.push({{arg.name}}.as_arg());
{% endif %}
{% endfor %}
}
{% else %}
Self::{{ incoming.name|camel }} => {}
{% endif %}
{% endfor %}
_ => unreachable!()
}
args
}
}
}
pub use {{interface.plainname}}::{{interface.plainname|camel}};
{% endfor %}
#[non_exhaustive]
#[derive(Debug)]
pub enum {{incoming_enum()}} {
{% for interface in interfaces %}
{{interface.plainname|camel}}({{interface.plainname}}::{{interface.plainname|camel}}, {{interface.plainname}}::{{incoming_enum()}}),
{% endfor %}
}
impl {{incoming_enum()}} {
pub(crate) fn op_name(interface: &str, operand: u32) -> Option<&'static str> {
match interface {
{% for interface in interfaces %}
"{{interface.protocol_name}}" =>
{{interface.plainname}}::{{incoming_enum()}}::op_name(operand),
{% endfor %}
_ => None,
}
}
pub(crate) fn parse(id: u64, interface: &str, operand: u32, bytes: &mut crate::ByteStream) -> Result<Self, crate::ParseError> {
match interface {
{% for interface in interfaces %}
"{{interface.protocol_name}}" => Ok(Self::{{interface.plainname|camel}}(
crate::Object::new(bytes.backend().clone(), id,
{% if extra.eis %}
false
{% else %}
true
{% endif %}
).downcast_unchecked(),
{{interface.plainname}}::{{incoming_enum()}}::parse(operand, bytes)?)
),
{% endfor %}
_ => Err(crate::ParseError::InvalidInterface),
}
}
}
impl crate::MessageEnum for {{incoming_enum()}} {
fn args(&self) -> Vec<crate::Arg<'_>> {
match self {
{% for interface in interfaces %}
Self::{{interface.plainname|camel}}(_, x) => x.args(),
{% endfor %}
}
}
}