ruwebframe 0.1.8

a simple webframe for rust actix-web, based on rudi and rbatis.
Documentation
use crate::rubase::BaseEntitySingle;
use crate::rudi::didto;
use syn::{File, Item, ItemImpl, Type, parse_file, visit::Visit};

#[derive(Default)]
pub struct RuAst {

}

impl BaseEntitySingle for RuAst {}
impl RuAst {
    pub fn new() -> RuAst {
        Default::default()
    }
    pub fn parse_file(file: &str) -> syn::Result<File> {
        println!("file: {}", file);
        parse_file("content")
    }
    pub fn parse_file_content(  content: &str) -> syn::Result<File> {
        parse_file(content)
    }
   
    pub fn find_base_entity(&self, file: &File) -> Vec<String> {
        self.find_trait(file, "BaseEntity")
    }
    pub fn find_base_entity_single(&self, file: &File) -> Vec<String> {
        self.find_trait(file, "BaseEntitySingle")
    }
    pub fn find_trait_default(&self, file: &File) -> Vec<String> {
        self.find_trait(file, "Default")
    }
    pub fn find_trait(&self, file: &File, traitName: &str) -> Vec<String> {
        let mut results = Vec::new();

        for item in &file.items {
            if let Item::Impl(item_impl) = item {
                // 1. 确认是 trait impl(不是 impl MyStruct {} 这种)
                if let Some((_, trait_path, _)) = &item_impl.trait_ {
                    // 2. 确认 trait 名是 BaseEntity
                    if let Some(seg) = trait_path.segments.last() {
                        if seg.ident == traitName {
                            // 3. 提取 self_ty 的名称(即 impl BaseEntity for <这里>)
                            if let Some(name) = type_to_string(&item_impl.self_ty) {
                                results.push(name);
                            }
                        }
                    }
                }
            }
        }

        results
    }

    pub fn find_all_default_content(&self, content: &str) -> Vec<String> {
        let ast = RuAst::parse_file_content(content).expect("parse failed");
        let ra = RuAst::new();
        // 方法1:简单遍历(只查顶层 items)
        ra.find_all_default(&ast)
    }
    pub fn find_base_entity_content(&self, content: &str) -> Vec<String> {
        let ast = RuAst::parse_file_content(content).expect("parse failed");
        let ra = RuAst::new();
        // 方法1:简单遍历(只查顶层 items)
        ra.find_base_entity(&ast)
    }
    pub fn find_base_entity_single_content(&self, content: &str) -> Vec<String> {
        let ast = RuAst::parse_file_content(content).expect("parse failed");
        let ra = RuAst::new();
        // 方法1:简单遍历(只查顶层 items)
        ra.find_base_entity_single(&ast)
    }
 
    pub fn find_base_entity_all(&self, file: &File) -> Vec<String> {
        let mut results = Vec::new();
        results.extend(self.find_base_entity(file));
        results.extend(self.find_base_entity_single(file));
        results
    }
    /// 检测结构体是否有 #[derive(Default)] 属性
    pub fn has_derive_default(&self, attrs: &[syn::Attribute]) -> bool {
        let mut has_default = false;
        for attr in attrs {
            if !attr.path().is_ident("derive") {
                continue;
            }
            if let syn::Meta::List(list) = &attr.meta {
                let _ = list.parse_nested_meta(|meta| {
                    if meta.path.is_ident("Default") {
                        has_default = true;
                    }
                    Ok(())
                });
                if has_default {
                    return true;
                }
            }
        }
        false
    }
    /// 查找所有带 #[derive(Default)] 的结构体
    pub fn find_derive_default(&self, file: &File) -> Vec<String> {
        let mut results = Vec::new();
        for item in &file.items {
            if let Item::Struct(item_struct) = item {
                if self.has_derive_default(&item_struct.attrs) {
                    results.push(item_struct.ident.to_string());
                }
            }
        }
        results
    }
    /// 查找所有 Default 实现(derive + impl),去重
    pub fn find_all_default(&self, file: &File) -> Vec<String> {
        let mut results = Vec::new();
        results.extend(self.find_derive_default(file));
        results.extend(self.find_trait(file, "Default"));
        results.sort();
        results.dedup();
        results
    }

    pub fn find_entity_all(&self, fileName: &str, content: &str) -> Vec<didto::StructInfo> {
        let mut results = Vec::<didto::StructInfo>::new();
        let ast = RuAst::parse_file_content(content).expect("parse failed");
        let default_set = self.find_all_default(&ast);

        let baseVec = self.find_base_entity(&ast);
        for structName in baseVec {
            let   structInfo = didto::StructInfo::new();
            let mut ss = structInfo.InitNew(
                false,
                default_set.contains(&structInfo.structName),
                structName,
                fileName.to_string(),
            );
             
            ss.ifDefault = default_set.contains(&ss.structName);
            results.push(ss);
        }
        let singleName = self.find_base_entity_single(&ast);
        for structName in singleName {
            let   structInfo = didto::StructInfo::new();
            let mut ss = structInfo.InitNew(
                true,
                default_set.contains(&structInfo.structName),
                structName,
                fileName.to_string(),
            );
            
            ss.ifDefault = default_set.contains(&ss.structName);
            results.push(ss);
        }
        results
    }
}

#[allow(dead_code)]
pub struct BaseEntityImplVisitor {
    pub results: Vec<String>,
}
fn type_to_string(ty: &Type) -> Option<String> {
    match ty {
        Type::Path(type_path) => {
            // 取路径最后一段,例如 std::foo::User -> "User"
            type_path.path.segments.last().map(|s| s.ident.to_string())
        }
        Type::Reference(r) => type_to_string(&r.elem), // &User -> User
        Type::Paren(p) => type_to_string(&p.elem),     // (User) -> User
        _ => None, // 遇到复杂类型(如 impl Trait、匿名结构体等)可扩展
    }
}
impl<'ast> Visit<'ast> for BaseEntityImplVisitor {
      fn visit_item_impl(&mut self, node: &'ast ItemImpl) {
        if let Some((_, trait_path, _)) = &node.trait_ {
            if let Some(seg) = trait_path.segments.last() {
                if seg.ident == "BaseEntity" {
                    if let Some(name) = type_to_string(&node.self_ty) {
                        self.results.push(name);
                    }
                }
            }
        }
        // 继续递归遍历(比如 mod 嵌套)
        syn::visit::visit_item_impl(self, node);
    }
}