blob: 45b592ee693ee8c0240272461f0abef4e07bbef2 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use syn::{Data, DataEnum, DataStruct, DataUnion, Field, Fields, Type};
pub trait DataExt {
fn nested_types(&self) -> Vec<&Type>;
}
impl DataExt for Data {
fn nested_types(&self) -> Vec<&Type> {
match self {
Data::Struct(strc) => strc.nested_types(),
Data::Enum(enm) => enm.nested_types(),
Data::Union(un) => un.nested_types(),
}
}
}
impl DataExt for DataStruct {
fn nested_types(&self) -> Vec<&Type> {
fields_to_types(&self.fields)
}
}
impl DataExt for DataEnum {
fn nested_types(&self) -> Vec<&Type> {
self.variants.iter().map(|var| fields_to_types(&var.fields)).fold(Vec::new(), |mut a, b| {
a.extend(b);
a
})
}
}
pub trait EnumExt {
fn is_c_like(&self) -> bool;
}
impl EnumExt for DataEnum {
fn is_c_like(&self) -> bool {
self.nested_types().is_empty()
}
}
impl DataExt for DataUnion {
fn nested_types(&self) -> Vec<&Type> {
field_iter_to_types(&self.fields.named)
}
}
fn fields_to_types(fields: &Fields) -> Vec<&Type> {
match fields {
Fields::Named(named) => field_iter_to_types(&named.named),
Fields::Unnamed(unnamed) => field_iter_to_types(&unnamed.unnamed),
Fields::Unit => Vec::new(),
}
}
fn field_iter_to_types<'a, I: IntoIterator<Item = &'a Field>>(fields: I) -> Vec<&'a Type> {
fields.into_iter().map(|f| &f.ty).collect()
}