use ink_analyzer_macro::{FromInkAttribute, FromSyntax};
use ra_ap_syntax::ast;
use crate::traits::{FromInkAttribute, FromSyntax, IsInkTrait};
use crate::tree::utils;
use crate::{InkArg, InkArgKind, InkAttrData, InkAttribute, Message};
#[derive(Debug, Clone, PartialEq, Eq, FromInkAttribute, FromSyntax)]
pub struct TraitDefinition {
#[macro_kind(TraitDefinition)]
ink_attr: InkAttrData<ast::Trait>,
#[arg_kind(Message)]
messages: Vec<Message>,
}
impl IsInkTrait for TraitDefinition {
fn trait_item(&self) -> Option<&ast::Trait> {
self.ink_attr.parent_ast()
}
}
impl TraitDefinition {
pub fn namespace_arg(&self) -> Option<InkArg> {
utils::ink_arg_by_kind(self.syntax(), InkArgKind::Namespace)
}
pub fn keep_attr_arg(&self) -> Option<InkArg> {
utils::ink_arg_by_kind(self.syntax(), InkArgKind::KeepAttr)
}
pub fn messages(&self) -> &[Message] {
&self.messages
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::*;
use test_utils::quote_as_str;
#[test]
fn cast_works() {
let ink_attr = parse_first_ink_attribute(quote_as_str! {
#[ink::trait_definition(namespace="my_namespace", keep_attr="foo,bar")]
pub trait MyTrait {
#[ink(message)]
fn my_message(&self);
#[ink(message)]
fn my_message_mut(&mut self);
}
});
let trait_definition = TraitDefinition::cast(ink_attr).unwrap();
assert!(trait_definition.namespace_arg().is_some());
assert!(trait_definition.keep_attr_arg().is_some());
assert_eq!(trait_definition.messages().len(), 2);
assert!(trait_definition.trait_item().is_some());
}
}