1+ use std:: collections:: HashMap ;
2+ use std:: process:: Command ;
3+ use serde:: { Deserialize , Serialize } ;
4+
5+ #[ derive( Debug , Deserialize , Serialize , Clone ) ]
6+ pub struct ApplicationInfo {
7+ #[ serde( rename = "_name" ) ]
8+ pub name : String ,
9+ #[ serde( rename = "obtained_from" ) ]
10+ pub obtained_from : String ,
11+ pub version : Option < String > ,
12+ #[ serde( rename = "lastModified" ) ]
13+ pub last_modified : String ,
14+ pub kind : Option < String > ,
15+ #[ serde( rename = "arch_kind" ) ]
16+ pub architecture : String ,
17+ #[ serde( rename = "signed_by" ) ]
18+ pub signed_by : Option < Vec < String > > ,
19+ pub path : Option < String > ,
20+ }
21+
22+ pub fn get_applications_info ( ) -> Result < HashMap < String , ApplicationInfo > , Box < dyn std:: error:: Error > > {
23+ let output = Command :: new ( "system_profiler" )
24+ . args ( & [ "SPApplicationsDataType" , "-json" ] )
25+ . output ( ) ?;
26+
27+ if !output. status . success ( ) {
28+ return Err ( format ! ( "命令执行失败: {}" , String :: from_utf8_lossy( & output. stderr) ) . into ( ) ) ;
29+ }
30+
31+ let json_str = String :: from_utf8 ( output. stdout ) ?;
32+
33+ // 直接解析为 HashMap
34+ let parsed: HashMap < String , Vec < ApplicationInfo > > = serde_json:: from_str ( & json_str) ?;
35+
36+ if let Some ( apps) = parsed. get ( "SPApplicationsDataType" ) {
37+ let applications: HashMap < String , ApplicationInfo > = apps
38+ . iter ( )
39+ . map ( |app| ( app. name . clone ( ) , app. clone ( ) ) )
40+ . collect ( ) ;
41+ Ok ( applications)
42+ } else {
43+ Err ( "未找到应用数据" . into ( ) )
44+ }
45+ }
46+
47+ // 扩展功能:应用过滤
48+ pub struct ApplicationFilter < ' a > {
49+ pub name_contains : Option < & ' a str > ,
50+ pub obtained_from : Option < & ' a str > ,
51+ pub architecture : Option < & ' a str > ,
52+ }
53+
54+ impl ApplicationInfo {
55+ pub fn matches_filter ( & self , filter : & ApplicationFilter ) -> bool {
56+ if let Some ( name) = filter. name_contains {
57+ if !self . name . to_lowercase ( ) . contains ( & name. to_lowercase ( ) ) {
58+ return false ;
59+ }
60+ }
61+
62+ if let Some ( source) = filter. obtained_from {
63+ if self . obtained_from != source {
64+ return false ;
65+ }
66+ }
67+
68+ if let Some ( arch) = filter. architecture {
69+ if self . architecture != arch {
70+ return false ;
71+ }
72+ }
73+
74+ true
75+ }
76+ }
77+
78+ // 使用过滤功能
79+ pub fn filter_applications ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
80+ let applications = get_applications_info ( ) ?;
81+
82+ let filter = ApplicationFilter {
83+ name_contains : Some ( "chrome" ) ,
84+ obtained_from : Some ( "Identified Developer" ) ,
85+ architecture : None ,
86+ } ;
87+
88+ println ! ( "过滤结果:" ) ;
89+ for app in applications. values ( ) . filter ( |a| a. matches_filter ( & filter) ) {
90+ println ! ( " - {} (来源: {})" , app. name, app. obtained_from) ;
91+ }
92+
93+ Ok ( ( ) )
94+ }
95+
96+ #[ allow( dead_code) ]
97+ fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
98+ match get_applications_info ( ) {
99+ Ok ( applications) => {
100+ println ! ( "找到 {} 个应用" , applications. len( ) ) ;
101+
102+ // 按来源分类统计
103+ let mut by_source: HashMap < String , Vec < & ApplicationInfo > > = HashMap :: new ( ) ;
104+ for app in applications. values ( ) {
105+ by_source. entry ( app. obtained_from . clone ( ) )
106+ . or_insert_with ( Vec :: new)
107+ . push ( app) ;
108+ }
109+
110+ // 打印统计信息
111+ println ! ( "\n 应用来源统计:" ) ;
112+ for ( source, apps) in & by_source {
113+ println ! ( " {}: {} 个应用" , source, apps. len( ) ) ;
114+ }
115+
116+ // 打印前10个应用的信息
117+ println ! ( "\n 前10个应用详情:" ) ;
118+ for ( i, app) in applications. values ( ) . take ( 10 ) . enumerate ( ) {
119+ println ! ( "{}. {}" , i + 1 , app. name) ;
120+ println ! ( " 版本: {:?}" , app. version) ;
121+ println ! ( " 来源: {}" , app. obtained_from) ;
122+ println ! ( " 架构: {}" , app. architecture) ;
123+ println ! ( " 签名: {:?}" , app. signed_by) ;
124+ println ! ( ) ;
125+ }
126+
127+ // 查找特定来源的应用
128+ println ! ( "来自 App Store 的应用:" ) ;
129+ for app in applications. values ( ) . filter ( |a| a. obtained_from == "Apple" ) {
130+ println ! ( " - {} (v{:?})" , app. name, app. version) ;
131+ }
132+ }
133+ Err ( e) => {
134+ eprintln ! ( "错误: {}" , e) ;
135+ }
136+ }
137+
138+ Ok ( ( ) )
139+ }
0 commit comments