Skip to main content

wowlab_tidy/languages/rust/rules/interop/
support.rs

1use ra_ap_syntax::{
2    AstNode,
3    ast::{self, HasAttrs, HasName, HasVisibility, VisibilityKind},
4};
5
6pub(super) use super::super::support::{is_inside_trait, is_item_or_impl_fn};
7
8pub(super) fn is_fully_public(node: &impl HasVisibility) -> bool {
9    node.visibility()
10        .is_some_and(|visibility| matches!(visibility.kind(), VisibilityKind::Pub))
11}
12
13#[expect(
14    clippy::needless_pass_by_value,
15    reason = "ra_ap_syntax traversal callbacks yield owned paths and this helper is a callback target"
16)]
17pub(super) fn path_names(path: ast::Path) -> Vec<String> {
18    super::super::support::path_names(&path)
19}
20
21#[expect(
22    clippy::needless_pass_by_value,
23    reason = "ra_ap_syntax traversal callbacks yield owned paths for last-segment checks"
24)]
25pub(super) fn path_last_is(path: ast::Path, expected: &str) -> bool {
26    path.segment()
27        .and_then(|segment| segment.name_ref())
28        .is_some_and(|name| name.text() == expected)
29}
30
31pub(super) fn path_matches(path: ast::Path, expected: &[&str]) -> bool {
32    path_names(path)
33        .iter()
34        .map(String::as_str)
35        .eq(expected.iter().copied())
36}
37
38#[expect(
39    clippy::needless_pass_by_value,
40    reason = "ra_ap_syntax traversal callbacks yield owned types for name extraction"
41)]
42pub(super) fn type_name(ty: ast::Type) -> Option<String> {
43    super::super::support::type_name(&ty)
44}
45
46pub(super) fn has_cfg_feature(node: &impl HasAttrs) -> bool {
47    node.attrs().any(|attr| {
48        attr.simple_name().is_some_and(|name| name == "cfg")
49            && attr
50                .syntax()
51                .descendants_with_tokens()
52                .filter_map(ra_ap_syntax::NodeOrToken::into_token)
53                .any(|token| token.text() == "feature")
54    })
55}
56
57pub(super) fn field_types(list: ast::FieldList) -> Vec<ast::Type> {
58    match list {
59        ast::FieldList::RecordFieldList(fields) => {
60            fields.fields().filter_map(|field| field.ty()).collect()
61        }
62        ast::FieldList::TupleFieldList(fields) => {
63            fields.fields().filter_map(|field| field.ty()).collect()
64        }
65    }
66}
67
68pub(super) fn enclosing_impl(function: &ast::Fn) -> Option<ast::Impl> {
69    function
70        .syntax()
71        .ancestors()
72        .skip(1)
73        .find_map(ast::Impl::cast)
74}
75
76pub(super) fn name_text(node: &impl HasName) -> Option<String> {
77    node.name().map(|name| name.text().to_string())
78}