rufio 0.33.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +103 -7
- data/bin/rufio +17 -2
- data/docs/CHANGELOG_v0.33.0.md +2 -2
- data/docs/CHANGELOG_v0.40.0.md +416 -0
- data/lib/rufio/application.rb +2 -2
- data/lib/rufio/async_scanner_fiber.rb +154 -0
- data/lib/rufio/async_scanner_promise.rb +66 -0
- data/lib/rufio/color_helper.rb +59 -6
- data/lib/rufio/command_logger.rb +3 -0
- data/lib/rufio/command_mode_ui.rb +18 -0
- data/lib/rufio/dialog_renderer.rb +68 -0
- data/lib/rufio/keybind_handler.rb +53 -2
- data/lib/rufio/native/rufio_zig.bundle +0 -0
- data/lib/rufio/native_scanner.rb +252 -233
- data/lib/rufio/native_scanner_zig.rb +215 -82
- data/lib/rufio/parallel_scanner.rb +173 -0
- data/lib/rufio/plugins/stop.rb +32 -0
- data/lib/rufio/renderer.rb +64 -0
- data/lib/rufio/screen.rb +184 -0
- data/lib/rufio/terminal_ui.rb +557 -34
- data/lib/rufio/text_utils.rb +30 -18
- data/lib/rufio/version.rb +1 -1
- data/lib/rufio.rb +5 -1
- data/lib_zig/rufio_native/Makefile +2 -1
- data/lib_zig/rufio_native/src/main.zig +328 -117
- data/lib_zig/rufio_native/src/main.zig.sync +205 -0
- metadata +10 -9
- data/lib/rufio/native/rufio_native.bundle +0 -0
- data/lib/rufio/native_scanner_magnus.rb +0 -194
- data/lib_rust/rufio_native/.cargo/config.toml +0 -2
- data/lib_rust/rufio_native/Cargo.lock +0 -346
- data/lib_rust/rufio_native/Cargo.toml +0 -18
- data/lib_rust/rufio_native/build.rs +0 -46
- data/lib_rust/rufio_native/src/lib.rs +0 -197
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const c = @cImport({
|
|
3
|
+
@cInclude("dirent.h");
|
|
4
|
+
@cInclude("sys/stat.h");
|
|
5
|
+
@cInclude("string.h");
|
|
6
|
+
@cInclude("stdlib.h");
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
/// ディレクトリエントリ情報(内部保持用)
|
|
10
|
+
const DirEntry = struct {
|
|
11
|
+
name: []u8,
|
|
12
|
+
is_dir: bool,
|
|
13
|
+
size: u64,
|
|
14
|
+
mtime: i64,
|
|
15
|
+
executable: bool,
|
|
16
|
+
hidden: bool,
|
|
17
|
+
|
|
18
|
+
fn deinit(self: *DirEntry) void {
|
|
19
|
+
c.free(self.name.ptr);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/// スキャナーコア(状態を保持)
|
|
24
|
+
const Scanner = struct {
|
|
25
|
+
entries: []DirEntry,
|
|
26
|
+
capacity: usize,
|
|
27
|
+
count: usize,
|
|
28
|
+
|
|
29
|
+
fn init() !*Scanner {
|
|
30
|
+
const self = @as(?*Scanner, @ptrCast(@alignCast(c.malloc(@sizeOf(Scanner))))) orelse return error.OutOfMemory;
|
|
31
|
+
self.*.capacity = 64;
|
|
32
|
+
const entries_size = self.*.capacity * @sizeOf(DirEntry);
|
|
33
|
+
const entries_ptr = c.malloc(entries_size) orelse {
|
|
34
|
+
c.free(self);
|
|
35
|
+
return error.OutOfMemory;
|
|
36
|
+
};
|
|
37
|
+
self.*.entries = @as([*]DirEntry, @ptrCast(@alignCast(entries_ptr)))[0..self.*.capacity];
|
|
38
|
+
self.*.count = 0;
|
|
39
|
+
return self;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fn deinit(self: *Scanner) void {
|
|
43
|
+
// 各エントリの名前を解放
|
|
44
|
+
for (self.entries[0..self.count]) |*entry| {
|
|
45
|
+
entry.deinit();
|
|
46
|
+
}
|
|
47
|
+
// エントリ配列を解放
|
|
48
|
+
c.free(self.entries.ptr);
|
|
49
|
+
// 自身を解放
|
|
50
|
+
c.free(self);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fn clear(self: *Scanner) void {
|
|
54
|
+
// 既存のエントリをクリア
|
|
55
|
+
for (self.entries[0..self.count]) |*entry| {
|
|
56
|
+
entry.deinit();
|
|
57
|
+
}
|
|
58
|
+
self.count = 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fn ensureCapacity(self: *Scanner, needed: usize) !void {
|
|
62
|
+
if (needed <= self.capacity) return;
|
|
63
|
+
|
|
64
|
+
const new_capacity = @max(needed, self.capacity * 2);
|
|
65
|
+
const new_size = new_capacity * @sizeOf(DirEntry);
|
|
66
|
+
const new_ptr = c.realloc(self.entries.ptr, new_size) orelse return error.OutOfMemory;
|
|
67
|
+
self.entries = @as([*]DirEntry, @ptrCast(@alignCast(new_ptr)))[0..new_capacity];
|
|
68
|
+
self.capacity = new_capacity;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn scan(self: *Scanner, path: [*:0]const u8, max_entries: usize) !void {
|
|
72
|
+
// 既存のエントリをクリア
|
|
73
|
+
self.clear();
|
|
74
|
+
|
|
75
|
+
const dir = c.opendir(path) orelse return error.CannotOpenDir;
|
|
76
|
+
defer _ = c.closedir(dir);
|
|
77
|
+
|
|
78
|
+
const path_len = c.strlen(path);
|
|
79
|
+
const path_slice = path[0..path_len];
|
|
80
|
+
|
|
81
|
+
while (c.readdir(dir)) |entry| {
|
|
82
|
+
// エントリ数制限チェック
|
|
83
|
+
if (max_entries > 0 and self.count >= max_entries) break;
|
|
84
|
+
|
|
85
|
+
const name_ptr = @as([*:0]const u8, @ptrCast(&entry.*.d_name));
|
|
86
|
+
const name_len = c.strlen(name_ptr);
|
|
87
|
+
const name_slice = name_ptr[0..name_len];
|
|
88
|
+
|
|
89
|
+
// "." と ".." をスキップ
|
|
90
|
+
if (std.mem.eql(u8, name_slice, ".") or std.mem.eql(u8, name_slice, "..")) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 容量確保
|
|
95
|
+
try self.ensureCapacity(self.count + 1);
|
|
96
|
+
|
|
97
|
+
// フルパスを構築
|
|
98
|
+
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
|
99
|
+
const full_path = std.fmt.bufPrintZ(&path_buf, "{s}/{s}", .{ path_slice, name_slice }) catch continue;
|
|
100
|
+
|
|
101
|
+
// ファイル情報を取得
|
|
102
|
+
var stat_buf: c.struct_stat = undefined;
|
|
103
|
+
if (c.lstat(full_path.ptr, &stat_buf) != 0) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 名前をコピー
|
|
108
|
+
const name_copy_ptr = c.malloc(name_len + 1) orelse return error.OutOfMemory;
|
|
109
|
+
const name_copy_bytes = @as([*]u8, @ptrCast(@alignCast(name_copy_ptr)));
|
|
110
|
+
const name_copy = name_copy_bytes[0..name_len];
|
|
111
|
+
@memcpy(name_copy, name_slice);
|
|
112
|
+
name_copy_bytes[name_len] = 0;
|
|
113
|
+
|
|
114
|
+
// エントリを追加
|
|
115
|
+
self.entries[self.count] = DirEntry{
|
|
116
|
+
.name = name_copy,
|
|
117
|
+
.is_dir = (stat_buf.st_mode & c.S_IFMT) == c.S_IFDIR,
|
|
118
|
+
.size = @intCast(stat_buf.st_size),
|
|
119
|
+
.mtime = @intCast(stat_buf.st_mtimespec.tv_sec),
|
|
120
|
+
.executable = (stat_buf.st_mode & c.S_IXUSR) != 0,
|
|
121
|
+
.hidden = name_slice[0] == '.',
|
|
122
|
+
};
|
|
123
|
+
self.count += 1;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// ============================================================
|
|
129
|
+
// ABI Boundary: Ruby ABI非依存・ハンドルベース
|
|
130
|
+
// ============================================================
|
|
131
|
+
|
|
132
|
+
/// スキャナーを作成(ハンドル返却)
|
|
133
|
+
export fn core_create() u64 {
|
|
134
|
+
const scanner = Scanner.init() catch return 0;
|
|
135
|
+
return @intFromPtr(scanner);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// ディレクトリをスキャン
|
|
139
|
+
export fn core_scan(handle: u64, path: [*:0]const u8) i32 {
|
|
140
|
+
if (handle == 0) return -1;
|
|
141
|
+
|
|
142
|
+
const scanner = @as(*Scanner, @ptrFromInt(handle));
|
|
143
|
+
scanner.scan(path, 0) catch return -1;
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/// 高速スキャン(エントリ数制限付き)
|
|
148
|
+
export fn core_scan_fast(handle: u64, path: [*:0]const u8, max_entries: usize) i32 {
|
|
149
|
+
if (handle == 0) return -1;
|
|
150
|
+
|
|
151
|
+
const scanner = @as(*Scanner, @ptrFromInt(handle));
|
|
152
|
+
scanner.scan(path, max_entries) catch return -1;
|
|
153
|
+
return 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/// エントリ数を取得
|
|
157
|
+
export fn core_get_count(handle: u64) usize {
|
|
158
|
+
if (handle == 0) return 0;
|
|
159
|
+
|
|
160
|
+
const scanner = @as(*Scanner, @ptrFromInt(handle));
|
|
161
|
+
return scanner.count;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/// 指定インデックスのエントリ名を取得
|
|
165
|
+
export fn core_get_name(handle: u64, index: usize, buf: [*]u8, buf_size: usize) usize {
|
|
166
|
+
if (handle == 0) return 0;
|
|
167
|
+
|
|
168
|
+
const scanner = @as(*Scanner, @ptrFromInt(handle));
|
|
169
|
+
if (index >= scanner.count) return 0;
|
|
170
|
+
|
|
171
|
+
const entry = &scanner.entries[index];
|
|
172
|
+
const copy_len = @min(entry.name.len, buf_size - 1);
|
|
173
|
+
@memcpy(buf[0..copy_len], entry.name[0..copy_len]);
|
|
174
|
+
buf[copy_len] = 0;
|
|
175
|
+
return copy_len;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/// 指定インデックスのエントリ属性を取得
|
|
179
|
+
export fn core_get_attrs(handle: u64, index: usize, is_dir: *u8, size: *u64, mtime: *i64, executable: *u8, hidden: *u8) i32 {
|
|
180
|
+
if (handle == 0) return -1;
|
|
181
|
+
|
|
182
|
+
const scanner = @as(*Scanner, @ptrFromInt(handle));
|
|
183
|
+
if (index >= scanner.count) return -1;
|
|
184
|
+
|
|
185
|
+
const entry = &scanner.entries[index];
|
|
186
|
+
is_dir.* = if (entry.is_dir) 1 else 0;
|
|
187
|
+
size.* = entry.size;
|
|
188
|
+
mtime.* = entry.mtime;
|
|
189
|
+
executable.* = if (entry.executable) 1 else 0;
|
|
190
|
+
hidden.* = if (entry.hidden) 1 else 0;
|
|
191
|
+
return 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/// スキャナーを破棄
|
|
195
|
+
export fn core_destroy(handle: u64) void {
|
|
196
|
+
if (handle == 0) return;
|
|
197
|
+
|
|
198
|
+
const scanner = @as(*Scanner, @ptrFromInt(handle));
|
|
199
|
+
scanner.deinit();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/// バージョン情報
|
|
203
|
+
export fn core_version() [*:0]const u8 {
|
|
204
|
+
return "3.0.0-handle-based";
|
|
205
|
+
}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rufio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.40.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- masisz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: io-console
|
|
@@ -131,6 +131,7 @@ files:
|
|
|
131
131
|
- docs/CHANGELOG_v0.32.0.md
|
|
132
132
|
- docs/CHANGELOG_v0.33.0.md
|
|
133
133
|
- docs/CHANGELOG_v0.4.0.md
|
|
134
|
+
- docs/CHANGELOG_v0.40.0.md
|
|
134
135
|
- docs/CHANGELOG_v0.5.0.md
|
|
135
136
|
- docs/CHANGELOG_v0.6.0.md
|
|
136
137
|
- docs/CHANGELOG_v0.7.0.md
|
|
@@ -143,6 +144,8 @@ files:
|
|
|
143
144
|
- info/welcome.md
|
|
144
145
|
- lib/rufio.rb
|
|
145
146
|
- lib/rufio/application.rb
|
|
147
|
+
- lib/rufio/async_scanner_fiber.rb
|
|
148
|
+
- lib/rufio/async_scanner_promise.rb
|
|
146
149
|
- lib/rufio/background_command_executor.rb
|
|
147
150
|
- lib/rufio/bookmark.rb
|
|
148
151
|
- lib/rufio/bookmark_manager.rb
|
|
@@ -164,33 +167,31 @@ files:
|
|
|
164
167
|
- lib/rufio/info_notice.rb
|
|
165
168
|
- lib/rufio/keybind_handler.rb
|
|
166
169
|
- lib/rufio/logger.rb
|
|
167
|
-
- lib/rufio/native/rufio_native.bundle
|
|
168
170
|
- lib/rufio/native/rufio_zig.bundle
|
|
169
171
|
- lib/rufio/native_scanner.rb
|
|
170
|
-
- lib/rufio/native_scanner_magnus.rb
|
|
171
172
|
- lib/rufio/native_scanner_zig.rb
|
|
173
|
+
- lib/rufio/parallel_scanner.rb
|
|
172
174
|
- lib/rufio/plugin.rb
|
|
173
175
|
- lib/rufio/plugin_config.rb
|
|
174
176
|
- lib/rufio/plugin_manager.rb
|
|
175
177
|
- lib/rufio/plugins/file_operations.rb
|
|
176
178
|
- lib/rufio/plugins/hello.rb
|
|
179
|
+
- lib/rufio/plugins/stop.rb
|
|
177
180
|
- lib/rufio/project_command.rb
|
|
178
181
|
- lib/rufio/project_log.rb
|
|
179
182
|
- lib/rufio/project_mode.rb
|
|
183
|
+
- lib/rufio/renderer.rb
|
|
184
|
+
- lib/rufio/screen.rb
|
|
180
185
|
- lib/rufio/selection_manager.rb
|
|
181
186
|
- lib/rufio/shell_command_completion.rb
|
|
182
187
|
- lib/rufio/terminal_ui.rb
|
|
183
188
|
- lib/rufio/text_utils.rb
|
|
184
189
|
- lib/rufio/version.rb
|
|
185
190
|
- lib/rufio/zoxide_integration.rb
|
|
186
|
-
- lib_rust/rufio_native/.cargo/config.toml
|
|
187
|
-
- lib_rust/rufio_native/Cargo.lock
|
|
188
|
-
- lib_rust/rufio_native/Cargo.toml
|
|
189
|
-
- lib_rust/rufio_native/build.rs
|
|
190
|
-
- lib_rust/rufio_native/src/lib.rs
|
|
191
191
|
- lib_zig/rufio_native/Makefile
|
|
192
192
|
- lib_zig/rufio_native/build.zig
|
|
193
193
|
- lib_zig/rufio_native/src/main.zig
|
|
194
|
+
- lib_zig/rufio_native/src/main.zig.sync
|
|
194
195
|
- publish_gem.zsh
|
|
195
196
|
- retag.sh
|
|
196
197
|
- test_delete/test1.txt
|
|
Binary file
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Rufio
|
|
4
|
-
# Magnus拡張のラッパー
|
|
5
|
-
# FFIを使わずに直接Rubyオブジェクトとして扱える
|
|
6
|
-
module NativeScannerMagnusLoader
|
|
7
|
-
LIB_PATH = File.expand_path('native/rufio_native.bundle', __dir__)
|
|
8
|
-
|
|
9
|
-
@loaded = false
|
|
10
|
-
@available = false
|
|
11
|
-
|
|
12
|
-
class << self
|
|
13
|
-
def load!
|
|
14
|
-
return @available if @loaded
|
|
15
|
-
|
|
16
|
-
@loaded = true
|
|
17
|
-
|
|
18
|
-
if File.exist?(LIB_PATH)
|
|
19
|
-
begin
|
|
20
|
-
# .bundleファイルを直接ロード
|
|
21
|
-
# 拡張子を外してrequireする
|
|
22
|
-
lib_path_without_ext = LIB_PATH.sub(/\.bundle$/, '')
|
|
23
|
-
require lib_path_without_ext
|
|
24
|
-
@available = defined?(Rufio::NativeScannerMagnus)
|
|
25
|
-
rescue LoadError => e
|
|
26
|
-
warn "Failed to load magnus extension: #{e.message}" if ENV['RUFIO_DEBUG']
|
|
27
|
-
@available = false
|
|
28
|
-
end
|
|
29
|
-
else
|
|
30
|
-
@available = false
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
@available
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def available?
|
|
37
|
-
load! unless @loaded
|
|
38
|
-
@available
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Magnus拡張が利用可能な場合のみロード
|
|
44
|
-
if NativeScannerMagnusLoader.load!
|
|
45
|
-
# NativeScannerにmagnusモードを追加
|
|
46
|
-
class NativeScanner
|
|
47
|
-
class << self
|
|
48
|
-
# magnusモードを追加
|
|
49
|
-
alias_method :original_mode=, :mode=
|
|
50
|
-
|
|
51
|
-
def mode=(value)
|
|
52
|
-
case value
|
|
53
|
-
when 'magnus'
|
|
54
|
-
if NativeScannerMagnusLoader.available?
|
|
55
|
-
@mode = 'magnus'
|
|
56
|
-
@current_library = nil # magnus は FFI を使わない
|
|
57
|
-
else
|
|
58
|
-
@mode = 'ruby'
|
|
59
|
-
@current_library = nil
|
|
60
|
-
end
|
|
61
|
-
else
|
|
62
|
-
send(:original_mode=, value)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# magnusスキャン
|
|
67
|
-
def scan_directory_with_magnus(path)
|
|
68
|
-
raise StandardError, "Directory does not exist: #{path}" unless Dir.exist?(path)
|
|
69
|
-
|
|
70
|
-
entries = NativeScannerMagnus.scan_directory(path)
|
|
71
|
-
|
|
72
|
-
# 結果の形式を統一(すでに正しい形式だが念のため)
|
|
73
|
-
entries.map do |entry|
|
|
74
|
-
{
|
|
75
|
-
name: entry[:name],
|
|
76
|
-
type: entry[:is_dir] ? 'directory' : 'file',
|
|
77
|
-
size: entry[:size],
|
|
78
|
-
mtime: entry[:mtime],
|
|
79
|
-
mode: 0,
|
|
80
|
-
executable: entry[:executable],
|
|
81
|
-
hidden: entry[:hidden]
|
|
82
|
-
}
|
|
83
|
-
end
|
|
84
|
-
rescue StandardError => e
|
|
85
|
-
raise StandardError, "Magnus scan failed: #{e.message}"
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# magnusで高速スキャン
|
|
89
|
-
def scan_directory_fast_with_magnus(path, max_entries)
|
|
90
|
-
raise StandardError, "Directory does not exist: #{path}" unless Dir.exist?(path)
|
|
91
|
-
|
|
92
|
-
entries = NativeScannerMagnus.scan_directory_fast(path, max_entries)
|
|
93
|
-
|
|
94
|
-
entries.map do |entry|
|
|
95
|
-
{
|
|
96
|
-
name: entry[:name],
|
|
97
|
-
type: entry[:is_dir] ? 'directory' : 'file',
|
|
98
|
-
size: entry[:size],
|
|
99
|
-
mtime: entry[:mtime],
|
|
100
|
-
mode: 0,
|
|
101
|
-
executable: entry[:executable],
|
|
102
|
-
hidden: entry[:hidden]
|
|
103
|
-
}
|
|
104
|
-
end
|
|
105
|
-
rescue StandardError => e
|
|
106
|
-
raise StandardError, "Magnus fast scan failed: #{e.message}"
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# scan_directoryメソッドを拡張
|
|
110
|
-
alias_method :original_scan_directory, :scan_directory
|
|
111
|
-
|
|
112
|
-
def scan_directory(path)
|
|
113
|
-
mode if @mode.nil?
|
|
114
|
-
|
|
115
|
-
case @mode
|
|
116
|
-
when 'magnus'
|
|
117
|
-
scan_directory_with_magnus(path)
|
|
118
|
-
else
|
|
119
|
-
original_scan_directory(path)
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# scan_directory_fastメソッドを拡張
|
|
124
|
-
alias_method :original_scan_directory_fast, :scan_directory_fast
|
|
125
|
-
|
|
126
|
-
def scan_directory_fast(path, max_entries = 1000)
|
|
127
|
-
mode if @mode.nil?
|
|
128
|
-
|
|
129
|
-
case @mode
|
|
130
|
-
when 'magnus'
|
|
131
|
-
scan_directory_fast_with_magnus(path, max_entries)
|
|
132
|
-
else
|
|
133
|
-
original_scan_directory_fast(path, max_entries)
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# versionメソッドを拡張
|
|
138
|
-
alias_method :original_version, :version
|
|
139
|
-
|
|
140
|
-
def version
|
|
141
|
-
mode if @mode.nil?
|
|
142
|
-
|
|
143
|
-
case @mode
|
|
144
|
-
when 'magnus'
|
|
145
|
-
NativeScannerMagnus.version
|
|
146
|
-
else
|
|
147
|
-
original_version
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# available_librariesを更新
|
|
152
|
-
alias_method :original_available_libraries, :available_libraries
|
|
153
|
-
|
|
154
|
-
def available_libraries
|
|
155
|
-
original = original_available_libraries
|
|
156
|
-
original.merge(magnus: NativeScannerMagnusLoader.available?)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
# autoモードの優先順位を更新(magnus > rust > go > ruby)
|
|
160
|
-
alias_method :original_auto_mode, :mode=
|
|
161
|
-
|
|
162
|
-
def mode=(value)
|
|
163
|
-
case value
|
|
164
|
-
when 'auto'
|
|
165
|
-
# 優先順位: Magnus > Rust > Go > Ruby
|
|
166
|
-
if NativeScannerMagnusLoader.available?
|
|
167
|
-
@mode = 'magnus'
|
|
168
|
-
@current_library = nil
|
|
169
|
-
elsif RustLib.available?
|
|
170
|
-
@mode = 'rust'
|
|
171
|
-
@current_library = RustLib
|
|
172
|
-
elsif GoLib.available?
|
|
173
|
-
@mode = 'go'
|
|
174
|
-
@current_library = GoLib
|
|
175
|
-
else
|
|
176
|
-
@mode = 'ruby'
|
|
177
|
-
@current_library = nil
|
|
178
|
-
end
|
|
179
|
-
when 'magnus'
|
|
180
|
-
if NativeScannerMagnusLoader.available?
|
|
181
|
-
@mode = 'magnus'
|
|
182
|
-
@current_library = nil
|
|
183
|
-
else
|
|
184
|
-
@mode = 'ruby'
|
|
185
|
-
@current_library = nil
|
|
186
|
-
end
|
|
187
|
-
else
|
|
188
|
-
send(:original_auto_mode, value)
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|