Skip to content

Commit 5570675

Browse files
committed
add search by text path
1 parent 5ec0d0e commit 5570675

File tree

8 files changed

+176
-16
lines changed

8 files changed

+176
-16
lines changed

Cargo.lock

Lines changed: 73 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ java_asm_macro = { path = "asm_macro", version = "0.0.15" } # JAVA_ASM_VERSION
2424
java_asm = { path = "asm", version = "0.0.15" } # JAVA_ASM_VERSION
2525
java_asm_server = { path = "asm_server", version = "0.0.15" } # JAVA_ASM_VERSION
2626

27+
trie-rs = "0.4.2"
2728
enum_dispatch = "0.3.13"
2829
zip = "2.2.0"
2930

asm_egui/src/top_bar.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::app::EguiApp;
2-
use egui::{Context, Ui};
2+
use egui::containers::PopupCloseBehavior;
3+
use egui::{popup_below_widget, Context, Ui};
34
use java_asm_server::AsmServer;
45
use std::ops::Deref;
56

@@ -35,16 +36,40 @@ impl EguiApp {
3536
}
3637

3738
fn file_path_input(&mut self, ui: &mut Ui) {
38-
let server_locked = self.server.lock();
39-
let Some(server) = server_locked.deref() else { return; };
40-
let accessor = server.accessor.lock();
41-
let Some(accessor) = accessor.deref() else { return; };
42-
// let all_classes: Vec<String> = accessor.read_classes().iter().map(|s| s.to_string()).collect();
4339
let mut locked_top = self.server_app.top().lock();
4440
let Some(file_path) = &mut locked_top.file_path else { return; };
45-
ui.label(file_path.to_string());
46-
// ui.add(AutoCompleteTextEdit::new(
47-
// file_path, all_classes,
48-
// ));
41+
let edit_path_ui = ui.text_edit_singleline(file_path);
42+
43+
let popup_id = ui.make_persistent_id("file_path_popup");
44+
if edit_path_ui.gained_focus() {
45+
let server_locked = self.server.lock();
46+
let Some(server) = server_locked.deref() else { return; };
47+
server.search(&mut locked_top);
48+
ui.memory_mut(|m| m.open_popup(popup_id));
49+
}
50+
51+
let search_results = locked_top.search_result.clone();
52+
drop(locked_top);
53+
54+
if search_results.is_empty() { return; }
55+
popup_below_widget(
56+
ui, popup_id, &edit_path_ui,
57+
PopupCloseBehavior::CloseOnClickOutside, |ui| {
58+
ui.vertical(|ui| {
59+
for result in search_results {
60+
if ui.label(result.to_string()).clicked() {
61+
let server_locked = self.server.lock();
62+
let Some(server) = server_locked.deref() else { return; };
63+
let mut content_locked = self.server_app.content().lock();
64+
let mut locked_top = self.server_app.top().lock();
65+
let accessor = server.accessor.lock();
66+
let Some(accessor) = accessor.deref() else { return; };
67+
server.switch_or_open_lock_free(
68+
&result, accessor, &mut content_locked, &mut locked_top,
69+
);
70+
}
71+
}
72+
})
73+
});
4974
}
5075
}

asm_server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ enum_dispatch = { workspace = true }
2222

2323
tokio = { workspace = true }
2424
parking_lot = { workspace = true }
25+
trie-rs = { workspace = true }

asm_server/src/impls/server.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::impls::apk_load::read_apk;
22
use crate::server::OpenFileError;
33
use crate::ui::{AppContainer, DirInfo, Left};
44
use crate::{AccessorEnum, AccessorMut, AsmServer, ServerMut};
5+
use java_asm::StrRef;
56
use log::info;
67
use std::io::{Read, Seek};
78
use std::ops::DerefMut;
@@ -14,6 +15,7 @@ use zip::ZipArchive;
1415

1516
pub enum ServerMessage {
1617
Progress(ProgressMessage),
18+
SearchResult(SearchResultMessage),
1719
}
1820

1921
pub struct ProgressMessage {
@@ -22,6 +24,10 @@ pub struct ProgressMessage {
2224
pub in_loading: bool,
2325
}
2426

27+
pub struct SearchResultMessage {
28+
pub result: Vec<StrRef>,
29+
}
30+
2531
pub struct FileOpenContext {
2632
pub path: String,
2733
pub start_time: Instant,
@@ -47,6 +53,9 @@ impl AsmServer {
4753
server_ref.loading_state.in_loading = progress.in_loading;
4854
server_ref.on_progress_update(&render_target);
4955
}
56+
ServerMessage::SearchResult(result) => {
57+
Self::on_search_result(result, &render_target);
58+
}
5059
}
5160
}
5261
});
@@ -83,6 +92,13 @@ impl AsmServer {
8392
(*top_mut).loading_state = current_loading_state.clone();
8493
}
8594

95+
fn on_search_result(result: SearchResultMessage, render_target: &AppContainer) {
96+
let result = result.result;
97+
let mut top = render_target.top().lock();
98+
let top_mut = top.deref_mut();
99+
(*top_mut).search_result = result;
100+
}
101+
86102
fn render_to_app(&self, app: AppContainer) {
87103
let classes = self.read_classes();
88104
let start = Instant::now();

asm_server/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use java_asm::smali::SmaliNode;
44
use java_asm::{DescriptorRef, StrRef};
55
use parking_lot::Mutex;
66
use std::sync::Arc;
7+
use trie_rs::Trie;
78

89
pub mod server;
910

@@ -16,10 +17,14 @@ pub struct AsmServer {
1617
pub loading_state: LoadingState,
1718
// when in loading state, the accessor is None.
1819
pub accessor: AccessorMut,
20+
classes: ArcNullable<Vec<StrRef>>,
21+
trie: ArcNullable<Trie<u8>>,
1922
}
2023

21-
pub type ServerMut = Arc<Mutex<Option<AsmServer>>>;
22-
type AccessorMut = Arc<Mutex<Option<AccessorEnum>>>;
24+
pub type ArcNullable<T> = Arc<Mutex<Option<T>>>;
25+
26+
pub type ServerMut = ArcNullable<AsmServer>;
27+
type AccessorMut = ArcNullable<AccessorEnum>;
2328

2429
#[derive(Default, Clone, Debug)]
2530
pub struct LoadingState {

asm_server/src/server.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::impls::server::FileOpenContext;
22
use crate::impls::util::new_tokio_thread;
33
use crate::ui::{AppContainer, Content, Tab, Top};
4-
use crate::{Accessor, AccessorEnum, AsmServer, LoadingState, ServerMut};
4+
use crate::{Accessor, AccessorEnum, ArcNullable, AsmServer, LoadingState, ServerMut};
55
use java_asm::smali::SmaliNode;
66
use java_asm::{AsmErr, StrRef};
77
use log::{error, info};
88
use std::fs::File;
9-
use std::ops::{Deref, DerefMut};
9+
use std::ops::Deref;
1010
use std::sync::Arc;
1111
use std::time::Instant;
12+
use trie_rs::{Trie, TrieBuilder};
1213
use zip::result::ZipError;
1314

1415
impl AsmServer {
@@ -20,9 +21,35 @@ impl AsmServer {
2021
err: None,
2122
},
2223
accessor: Default::default(),
24+
classes: Default::default(),
25+
trie: Default::default(),
2326
}
2427
}
2528

29+
pub fn get_classes(&self) -> &ArcNullable<Vec<StrRef>> {
30+
let mut current = self.classes.lock();
31+
if current.is_some() { return &self.classes; }
32+
let accessor_locked = self.accessor.lock();
33+
let Some(accessor) = accessor_locked.deref() else { return &self.classes; };
34+
let classes = accessor.read_classes();
35+
current.replace(classes);
36+
&self.classes
37+
}
38+
39+
pub fn get_trie(&self) -> &ArcNullable<Trie<u8>> {
40+
let mut current = self.trie.lock();
41+
if current.is_some() { return &self.trie; }
42+
let classes_locked = self.get_classes().lock();
43+
let Some(classes) = classes_locked.deref() else { return &self.trie; };
44+
let mut trie_builder = TrieBuilder::new();
45+
for class in classes.iter() {
46+
trie_builder.push(class.to_string());
47+
};
48+
let trie = trie_builder.build();
49+
current.replace(trie);
50+
&self.trie
51+
}
52+
2653
pub fn smart_open(server: ServerMut, path: &str, render_target: AppContainer) {
2754
let context = FileOpenContext { path: path.to_string(), start_time: Instant::now() };
2855
new_tokio_thread(|runtime| async move {
@@ -74,7 +101,10 @@ impl AsmServer {
74101
}
75102

76103
let smali = accessor.read_content(file_key);
77-
let Some(smali) = smali else { return; };
104+
let Some(smali) = smali else {
105+
error!("content with key: `{file_key}` not found.");
106+
return;
107+
};
78108
let current_tab = Tab {
79109
selected: false,
80110
file_key: Arc::from(file_key),
@@ -87,6 +117,14 @@ impl AsmServer {
87117

88118
top.file_path = Some(file_key.to_string());
89119
}
120+
121+
pub fn search(&self, top: &mut Top) {
122+
let Some(query) = &top.file_path else { return; };
123+
let trie_locked = self.get_trie().lock();
124+
let Some(trie) = trie_locked.deref() else { return; };
125+
let results: Vec<String> = trie.predictive_search(query).collect();
126+
top.search_result = results.into_iter().map(StrRef::from).collect();
127+
}
90128
}
91129

92130

asm_server/src/ui/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::ui::log::LogHolder;
66
use crate::ui::AbsFile::{Dir, File};
77
use crate::LoadingState;
88
use java_asm::smali::SmaliNode;
9-
use java_asm::StrRef;
9+
use java_asm::{DescriptorRef, StrRef};
1010
use ::log::Level;
1111
use parking_lot::Mutex;
1212
use std::collections::BTreeMap;
@@ -41,6 +41,7 @@ impl AppContainer {
4141
pub struct Top {
4242
pub loading_state: LoadingState,
4343
pub file_path: Option<String>,
44+
pub search_result: Vec<StrRef>,
4445
}
4546

4647
#[derive(Default, Clone, Debug)]

0 commit comments

Comments
 (0)