rust: search

项目结构:

ruby 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:42 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : models.rs
/// 珠宝领域模型
#[derive(Debug, Clone)]
pub struct JewelryItem {
    pub id: String,
    pub name: String,
    pub category: JewelryCategory,
    pub weight: f64,
    pub price: f64,
    pub stock: u32,
}

/// 珠宝分类(枚举,可扩展)
#[derive(Debug, Clone, PartialEq)]
pub enum JewelryCategory {
    Ring,
    Necklace,
    Bracelet,
    Earring,
    Pendant,
    Other(String),
}

/// 钻石领域模型
#[derive(Debug, Clone)]
pub struct Diamond {
    pub cert_no: String,
    pub carat: f64,
    pub color: String,
    pub clarity: String,
    pub cut: String,
    pub price_per_carat: f64,
}

/// 会员等级领域模型
#[derive(Debug, Clone)]
pub struct MemberLevel {
    pub min_consumption: f64,
    pub level_name: String,
    pub discount: f64,
}


//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:42 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : repositories.rs
use super::models::{JewelryItem, Diamond, MemberLevel};

/// 珠宝仓储接口
pub trait JewelryRepository: Send + Sync {
    fn find_by_id(&self, id: &str) -> Option<JewelryItem>;
    fn find_by_category(&self, category: &str) -> Vec<JewelryItem>;
    fn find_all(&self) -> Vec<JewelryItem>;
}

/// 钻石仓储接口
pub trait DiamondRepository: Send + Sync {
    fn find_by_carat(&self, target_carat: f64, tolerance: f64) -> Option<Diamond>;
    fn find_all_sorted_by_carat(&self) -> Vec<Diamond>;
}

/// 会员仓储接口
pub trait MemberLevelRepository: Send + Sync {
    fn find_level_by_consumption(&self, consumption: f64) -> Option<MemberLevel>;
}


//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:43 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : services.rs
use super::models::{Diamond, JewelryItem};

/// 珠宝搜索领域服务
pub struct JewelrySearchService;

impl JewelrySearchService {
    /// 线性搜索:根据名称模糊匹配
    pub fn search_by_name<'a>(items: &'a [JewelryItem], keyword: &str) -> Vec<&'a JewelryItem> {
        items
            .iter()
            .filter(|item| item.name.to_lowercase().contains(&keyword.to_lowercase()))
            .collect()
    }

    /// 价格区间筛选
    pub fn filter_by_price_range<'a>(items: &'a [JewelryItem], min: f64, max: f64) -> Vec<&'a JewelryItem> {
        items
            .iter()
            .filter(|item| item.price >= min && item.price <= max)
            .collect()
    }
}

/// 钻石搜索领域服务
pub struct DiamondSearchService;

impl DiamondSearchService {
    /// 二分查找:在已排序的钻石中查找最接近目标克拉的钻石
    pub fn binary_search_by_carat(diamonds: &[Diamond], target_carat: f64, tolerance: f64) -> Option<usize> {
        let mut left = 0;
        let mut right = diamonds.len();

        while left < right {
            let mid = left + (right - left) / 2;
            let diff = diamonds[mid].carat - target_carat;

            if diff.abs() <= tolerance {
                return Some(mid);
            } else if diamonds[mid].carat < target_carat {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        None
    }
}
ruby 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:45 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : commands.rs
// 命令处理器(用于写操作,如新增/更新珠宝)
// 此处留空,可根据需要扩展
pub struct JewelryCommandHandler;


//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:44 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : dto.rs
use crate::domain::models::JewelryCategory;

/// 珠宝搜索请求 DTO
#[derive(Debug)]
pub struct SearchJewelryRequest {
    pub keyword: Option<String>,
    pub category: Option<JewelryCategory>,
    pub min_price: Option<f64>,
    pub max_price: Option<f64>,
}

/// 珠宝搜索结果 DTO
#[derive(Debug)]
pub struct JewelrySearchResult {
    pub id: String,
    pub name: String,
    pub category: String,
    pub price: f64,
    pub stock: u32,
}

/// 钻石搜索请求 DTO
#[derive(Debug)]
pub struct SearchDiamondRequest {
    pub target_carat: f64,
    pub tolerance: f64,
}

/// 会员等级查询请求 DTO
#[derive(Debug)]
pub struct GetMemberLevelRequest {
    pub consumption: f64,
}


//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:44 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : queries.rs
use crate::domain::repositories::{JewelryRepository, DiamondRepository, MemberLevelRepository};
use crate::domain::services::{JewelrySearchService, DiamondSearchService};
use super::dto::*;

/// 珠宝查询处理器
pub struct JewelryQueryHandler<R: JewelryRepository> {
    repository: R,
}

impl<R: JewelryRepository> JewelryQueryHandler<R> {
    pub fn new(repository: R) -> Self {
        Self { repository }
    }

    pub fn search(&self, request: SearchJewelryRequest) -> Vec<JewelrySearchResult> {
        let all_items = self.repository.find_all();

        let mut results: Vec<&crate::domain::models::JewelryItem> = all_items.iter().collect();

        // 按关键词过滤
        if let Some(ref keyword) = request.keyword {
            results = JewelrySearchService::search_by_name(
                &results.iter().map(|i| (*i).clone()).collect::<Vec<_>>(),
                keyword,
            )
                .into_iter()
                .map(|item| {
                    // 重新从原始列表中获取引用
                    all_items.iter().find(|i| i.id == item.id).unwrap()
                })
                .collect();
        }

        // 按分类过滤
        if let Some(ref category) = request.category {
            results.retain(|item| &item.category == category);
        }

        // 按价格区间过滤
        if let (Some(min), Some(max)) = (request.min_price, request.max_price) {
            results = JewelrySearchService::filter_by_price_range(
                &results.iter().map(|i| (*i).clone()).collect::<Vec<_>>(),
                min,
                max,
            )
                .into_iter()
                .map(|item| {
                    all_items.iter().find(|i| i.id == item.id).unwrap()
                })
                .collect();
        }

        results
            .into_iter()
            .map(|item| JewelrySearchResult {
                id: item.id.clone(),
                name: item.name.clone(),
                category: format!("{:?}", item.category),
                price: item.price,
                stock: item.stock,
            })
            .collect()
    }
}

/// 钻石查询处理器
pub struct DiamondQueryHandler<R: DiamondRepository> {
    repository: R,
}

impl<R: DiamondRepository> DiamondQueryHandler<R> {
    pub fn new(repository: R) -> Self {
        Self { repository }
    }

    pub fn search_by_carat(&self, request: SearchDiamondRequest) -> Option<crate::domain::models::Diamond> {
        let diamonds = self.repository.find_all_sorted_by_carat();
        let idx = DiamondSearchService::binary_search_by_carat(
            &diamonds,
            request.target_carat,
            request.tolerance,
        );
        idx.map(|i| diamonds[i].clone())
    }
}

/// 会员等级查询处理器
pub struct MemberLevelQueryHandler<R: MemberLevelRepository> {
    repository: R,
}

impl<R: MemberLevelRepository> MemberLevelQueryHandler<R> {
    pub fn new(repository: R) -> Self {
        Self { repository }
    }

    pub fn get_level(&self, consumption: f64) -> Option<crate::domain::models::MemberLevel> {
        self.repository.find_level_by_consumption(consumption)
    }
}


//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:47 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : api.rs
use crate::application::queries::{JewelryQueryHandler, DiamondQueryHandler, MemberLevelQueryHandler};
use crate::application::dto::*;

/// 珠宝搜索 API
pub struct JewelrySearchApi {
    jewelry_handler: JewelryQueryHandler<crate::infrastructure::repositories::InMemoryJewelryRepository>,
    diamond_handler: DiamondQueryHandler<crate::infrastructure::repositories::InMemoryDiamondRepository>,
    member_handler: MemberLevelQueryHandler<crate::infrastructure::repositories::InMemoryMemberLevelRepository>,
}

impl JewelrySearchApi {
    pub fn new(
        jewelry_handler: JewelryQueryHandler<crate::infrastructure::repositories::InMemoryJewelryRepository>,
        diamond_handler: DiamondQueryHandler<crate::infrastructure::repositories::InMemoryDiamondRepository>,
        member_handler: MemberLevelQueryHandler<crate::infrastructure::repositories::InMemoryMemberLevelRepository>,
    ) -> Self {
        Self {
            jewelry_handler,
            diamond_handler,
            member_handler,
        }
    }

    pub fn search_jewelry(&self, request: SearchJewelryRequest) -> Vec<JewelrySearchResult> {
        self.jewelry_handler.search(request)
    }

    pub fn search_diamond(&self, request: SearchDiamondRequest) -> Option<crate::domain::models::Diamond> {
        self.diamond_handler.search_by_carat(request)
    }

    pub fn get_member_level(&self, consumption: f64) -> Option<crate::domain::models::MemberLevel> {
        self.member_handler.get_level(consumption)
    }
}

调用:

ruby 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/9/27 23:41 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : jewelrysearch
//!# File      : main.rs
mod domain;
mod application;
mod infrastructure;
mod interfaces;



use std::sync::Arc;
use application::dto::*;
use infrastructure::data_store::InMemoryDataStore;
use infrastructure::repositories::*;
use application::queries::*;
use interfaces::api::JewelrySearchApi;

fn main() {
    // 初始化数据存储
    let store = Arc::new(InMemoryDataStore::new());

    // 初始化仓储
    let jewelry_repo = InMemoryJewelryRepository::new(store.clone());
    let diamond_repo = InMemoryDiamondRepository::new(store.clone());
    let member_repo = InMemoryMemberLevelRepository::new(store.clone());

    // 初始化查询处理器
    let jewelry_handler = JewelryQueryHandler::new(jewelry_repo);
    let diamond_handler = DiamondQueryHandler::new(diamond_repo);
    let member_handler = MemberLevelQueryHandler::new(member_repo);

    // 初始化 API
    let api = JewelrySearchApi::new(jewelry_handler, diamond_handler, member_handler);

    // 示例 1:搜索珠宝
    println!("=== 搜索珠宝 ===");
    let request = SearchJewelryRequest {
        keyword: Some("戒指".to_string()),
        category: None,
        min_price: None,
        max_price: None,
    };
    let results = api.search_jewelry(request);
    for r in &results {
        println!("  {} | {} | {:.2}元 | 库存: {}", r.name, r.category, r.price, r.stock);
    }

    // 示例 2:搜索钻石
    println!("\n=== 搜索1克拉钻石 ===");
    let diamond_request = SearchDiamondRequest {
        target_carat: 1.00,
        tolerance: 0.01,
    };
    match api.search_diamond(diamond_request) {
        Some(d) => {
            println!("  证书号: {}", d.cert_no);
            println!("  克拉: {} | 颜色: {} | 净度: {} | 切工: {}", d.carat, d.color, d.clarity, d.cut);
            println!("  单价: {:.0}元/克拉 | 总价: {:.2}元", d.price_per_carat, d.carat * d.price_per_carat);
        }
        None => println!("  未找到匹配的钻石"),
    }

    // 示例 3:查询会员等级
    println!("\n=== 查询会员等级 ===");
    match api.get_member_level(25000.0) {
        Some(level) => {
            println!("  等级: {} | 折扣: {:.0}折", level.level_name, level.discount * 10.0);
        }
        None => println!("  无会员等级"),
    }
}

输出:

相关推荐
the局外人1 小时前
读懂LangGraph 的分支执行逻辑
后端·langchain·llm
SimonKing1 小时前
Stream-Nexus:我的轻量级推送中间件(sse、websocket)终于定下来了
java·后端·程序员
重生之小比特1 小时前
【C++进阶】封装红⿊树实现mymap和myset
开发语言·c++
打工仔折腾 AI1 小时前
网易UU远程实测:手机控电脑做Python开发和Agent调试的真实体验
人工智能·后端·python·智能手机·性能优化·电脑·ai agent 实战
边境悍匪1 小时前
蜗牛学苑 Java 智能体学习 Day49|贯穿项目 5 订单下单业务 思维导图复盘
java·开发语言·spring boot·学习·阿里云
“AI国潮设计-小江”2 小时前
【AIGC实战】Python+SDXL打造潮汕国潮IP:英歌舞麻将的自动化生成与商用思路
开发语言·人工智能·python·prompt·aigc
YYYing.2 小时前
【设计模式系列 (四) 】建造者模式
c++·后端·设计模式·建造者模式·c/c++
Roadinforest2 小时前
Spring Boot 4 六步入门实录:从 Hello World 到一个能交付的 Todo API
java·开发语言·spring boot·spring
IT_陈寒2 小时前
用Vue时这个响应式陷阱坑了我一整天
前端·人工智能·后端