alpha repo init
This commit is contained in:
2028
tui-rust/Cargo.lock
generated
Normal file
2028
tui-rust/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
tui-rust/Cargo.toml
Normal file
16
tui-rust/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "atlas-tui"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ratatui = "0.27"
|
||||
crossterm = "0.28"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
reqwest = { version = "0.12", features = ["json"] }
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
anyhow = "1.0"
|
||||
dirs = "5.0"
|
||||
|
||||
|
||||
50
tui-rust/README.md
Normal file
50
tui-rust/README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# AtlasOS TUI (Rust + ratatui)
|
||||
|
||||
Terminal User Interface untuk AtlasOS yang dibangun dengan Rust dan ratatui.
|
||||
|
||||
## Features
|
||||
|
||||
- Modern TUI dengan ratatui
|
||||
- Navigasi dengan keyboard
|
||||
- Support untuk semua fitur AtlasOS API
|
||||
- Login authentication
|
||||
- Real-time data display
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
cd tui-rust
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
Binary akan ada di `target/release/atlas-tui`
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
./target/release/atlas-tui
|
||||
```
|
||||
|
||||
Atau set environment variable untuk API URL:
|
||||
```bash
|
||||
ATLAS_API_URL=http://localhost:8080 ./target/release/atlas-tui
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Rust 1.70+
|
||||
- ratatui 0.27
|
||||
- crossterm 0.28
|
||||
- reqwest (untuk HTTP client)
|
||||
- tokio (untuk async runtime)
|
||||
|
||||
## Status
|
||||
|
||||
🚧 **Work in Progress** - Implementasi dasar sudah ada, masih perlu:
|
||||
- Complete semua menu handlers
|
||||
- Input forms untuk create/edit operations
|
||||
- Better error handling
|
||||
- Loading states
|
||||
- Data tables untuk lists
|
||||
|
||||
|
||||
173
tui-rust/src/api.rs
Normal file
173
tui-rust/src/api.rs
Normal file
@@ -0,0 +1,173 @@
|
||||
use anyhow::{Context, Result};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct APIClient {
|
||||
base_url: String,
|
||||
client: Client,
|
||||
token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LoginRequest {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LoginResponse {
|
||||
pub token: String,
|
||||
pub user: Option<Value>,
|
||||
}
|
||||
|
||||
impl APIClient {
|
||||
pub fn new(base_url: String) -> Self {
|
||||
Self {
|
||||
base_url,
|
||||
client: Client::new(),
|
||||
token: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_token(&mut self, token: String) {
|
||||
self.token = Some(token);
|
||||
}
|
||||
|
||||
pub fn has_token(&self) -> bool {
|
||||
self.token.is_some()
|
||||
}
|
||||
|
||||
pub async fn login(&mut self, username: String, password: String) -> Result<LoginResponse> {
|
||||
let url = format!("{}/api/v1/auth/login", self.base_url);
|
||||
let req = LoginRequest { username, password };
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.post(&url)
|
||||
.json(&req)
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send login request")?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
let text = response.text().await.unwrap_or_default();
|
||||
anyhow::bail!("Login failed: {}", text);
|
||||
}
|
||||
|
||||
let login_resp: LoginResponse = response
|
||||
.json()
|
||||
.await
|
||||
.context("Failed to parse login response")?;
|
||||
|
||||
self.set_token(login_resp.token.clone());
|
||||
Ok(login_resp)
|
||||
}
|
||||
|
||||
pub async fn get(&self, path: &str) -> Result<Value> {
|
||||
let url = format!("{}{}", self.base_url, path);
|
||||
let mut request = self.client.get(&url);
|
||||
|
||||
if let Some(ref token) = self.token {
|
||||
request = request.bearer_auth(token);
|
||||
}
|
||||
|
||||
let response = request
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send GET request")?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
let text = response.text().await.unwrap_or_default();
|
||||
anyhow::bail!("API error (status {}): {}", status, text);
|
||||
}
|
||||
|
||||
let json: Value = response
|
||||
.json()
|
||||
.await
|
||||
.context("Failed to parse JSON response")?;
|
||||
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
pub async fn post(&self, path: &str, body: &Value) -> Result<Value> {
|
||||
let url = format!("{}{}", self.base_url, path);
|
||||
let mut request = self.client.post(&url).json(body);
|
||||
|
||||
if let Some(ref token) = self.token {
|
||||
request = request.bearer_auth(token);
|
||||
}
|
||||
|
||||
let response = request
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send POST request")?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
let text = response.text().await.unwrap_or_default();
|
||||
anyhow::bail!("API error (status {}): {}", status, text);
|
||||
}
|
||||
|
||||
let json: Value = response
|
||||
.json()
|
||||
.await
|
||||
.context("Failed to parse JSON response")?;
|
||||
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
pub async fn delete(&self, path: &str) -> Result<()> {
|
||||
let url = format!("{}{}", self.base_url, path);
|
||||
let mut request = self.client.delete(&url);
|
||||
|
||||
if let Some(ref token) = self.token {
|
||||
request = request.bearer_auth(token);
|
||||
}
|
||||
|
||||
let response = request
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send DELETE request")?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
let text = response.text().await.unwrap_or_default();
|
||||
anyhow::bail!("API error (status {}): {}", status, text);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn put(&self, path: &str, body: &Value) -> Result<Value> {
|
||||
let url = format!("{}{}", self.base_url, path);
|
||||
let mut request = self.client.put(&url).json(body);
|
||||
|
||||
if let Some(ref token) = self.token {
|
||||
request = request.bearer_auth(token);
|
||||
}
|
||||
|
||||
let response = request
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send PUT request")?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
let text = response.text().await.unwrap_or_default();
|
||||
anyhow::bail!("API error (status {}): {}", status, text);
|
||||
}
|
||||
|
||||
let json: Value = response
|
||||
.json()
|
||||
.await
|
||||
.context("Failed to parse JSON response")?;
|
||||
|
||||
Ok(json)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
189
tui-rust/src/app.rs
Normal file
189
tui-rust/src/app.rs
Normal file
@@ -0,0 +1,189 @@
|
||||
use crate::api::APIClient;
|
||||
use crate::ui;
|
||||
use anyhow::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use ratatui::backend::Backend;
|
||||
use ratatui::Terminal;
|
||||
use ratatui::widgets::ListState;
|
||||
use std::io;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum LoginStep {
|
||||
Username,
|
||||
Password,
|
||||
Done,
|
||||
}
|
||||
|
||||
pub enum AppState {
|
||||
Login,
|
||||
MainMenu,
|
||||
ZFSMenu,
|
||||
StorageMenu,
|
||||
SnapshotMenu,
|
||||
SystemMenu,
|
||||
BackupMenu,
|
||||
UserMenu,
|
||||
ServiceMenu,
|
||||
ViewingData,
|
||||
InputPrompt(String), // Prompt message
|
||||
Exit,
|
||||
}
|
||||
|
||||
pub struct App {
|
||||
pub api_client: APIClient,
|
||||
pub state: AppState,
|
||||
pub input_buffer: String,
|
||||
pub input_mode: bool,
|
||||
pub error_message: Option<String>,
|
||||
pub success_message: Option<String>,
|
||||
pub data: Option<serde_json::Value>,
|
||||
pub selected_index: usize,
|
||||
pub list_state: ListState,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub login_step: LoginStep,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(api_url: String) -> Self {
|
||||
Self {
|
||||
api_client: APIClient::new(api_url),
|
||||
state: AppState::Login,
|
||||
input_buffer: String::new(),
|
||||
input_mode: false,
|
||||
error_message: None,
|
||||
success_message: None,
|
||||
data: None,
|
||||
selected_index: 0,
|
||||
list_state: ListState::default(),
|
||||
username: String::new(),
|
||||
password: String::new(),
|
||||
login_step: LoginStep::Username,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run<B: Backend>(&mut self, terminal: &mut Terminal<B>) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|f| ui::draw(f, self))?;
|
||||
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => {
|
||||
if matches!(self.state, AppState::Login) {
|
||||
self.state = AppState::Exit;
|
||||
break;
|
||||
} else {
|
||||
self.state = AppState::MainMenu;
|
||||
}
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
self.handle_enter().await?;
|
||||
}
|
||||
KeyCode::Backspace => {
|
||||
if self.input_mode {
|
||||
self.input_buffer.pop();
|
||||
}
|
||||
}
|
||||
KeyCode::Char(c) => {
|
||||
if self.input_mode {
|
||||
self.input_buffer.push(c);
|
||||
} else {
|
||||
self.handle_key(c).await?;
|
||||
}
|
||||
}
|
||||
KeyCode::Up => {
|
||||
if self.selected_index > 0 {
|
||||
self.selected_index -= 1;
|
||||
}
|
||||
self.list_state.select(Some(self.selected_index));
|
||||
}
|
||||
KeyCode::Down => {
|
||||
self.selected_index += 1;
|
||||
self.list_state.select(Some(self.selected_index));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if matches!(self.state, AppState::Exit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_enter(&mut self) -> Result<()> {
|
||||
match &self.state {
|
||||
AppState::Login => {
|
||||
// Login will be handled in input mode
|
||||
if !self.input_mode {
|
||||
self.input_mode = true;
|
||||
self.input_buffer.clear();
|
||||
}
|
||||
}
|
||||
AppState::MainMenu => {
|
||||
match self.selected_index {
|
||||
0 => self.state = AppState::ZFSMenu,
|
||||
1 => self.state = AppState::StorageMenu,
|
||||
2 => self.state = AppState::SnapshotMenu,
|
||||
3 => self.state = AppState::SystemMenu,
|
||||
4 => self.state = AppState::BackupMenu,
|
||||
5 => self.state = AppState::UserMenu,
|
||||
6 => self.state = AppState::ServiceMenu,
|
||||
_ => {}
|
||||
}
|
||||
self.selected_index = 0;
|
||||
self.list_state.select(Some(0));
|
||||
}
|
||||
AppState::ZFSMenu => {
|
||||
// Handle ZFS menu selection
|
||||
self.handle_zfs_action().await?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_key(&mut self, c: char) -> Result<()> {
|
||||
match c {
|
||||
'1'..='9' => {
|
||||
if matches!(self.state, AppState::MainMenu) {
|
||||
let idx = (c as usize) - ('1' as usize);
|
||||
if idx < 7 {
|
||||
self.selected_index = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
'0' => {
|
||||
if matches!(self.state, AppState::MainMenu) {
|
||||
self.state = AppState::Exit;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_zfs_action(&mut self) -> Result<()> {
|
||||
match self.selected_index {
|
||||
0 => {
|
||||
// List pools
|
||||
match self.api_client.get("/api/v1/pools").await {
|
||||
Ok(data) => {
|
||||
self.data = Some(data);
|
||||
self.state = AppState::ViewingData;
|
||||
}
|
||||
Err(e) => {
|
||||
self.error_message = Some(format!("Error: {}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
55
tui-rust/src/main.rs
Normal file
55
tui-rust/src/main.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use anyhow::Result;
|
||||
use crossterm::{
|
||||
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use ratatui::{
|
||||
backend::CrosstermBackend,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Line, Span},
|
||||
widgets::{Block, Borders, List, ListItem, ListState, Paragraph, Wrap},
|
||||
Frame, Terminal,
|
||||
};
|
||||
use std::io;
|
||||
|
||||
mod api;
|
||||
mod app;
|
||||
mod ui;
|
||||
|
||||
use app::App;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Setup terminal
|
||||
enable_raw_mode()?;
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
|
||||
// Get API URL from environment or use default
|
||||
let api_url = std::env::var("ATLAS_API_URL")
|
||||
.unwrap_or_else(|_| "http://localhost:8080".to_string());
|
||||
|
||||
// Create app
|
||||
let mut app = App::new(api_url);
|
||||
let res = app.run(&mut terminal).await;
|
||||
|
||||
// Restore terminal
|
||||
disable_raw_mode()?;
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
LeaveAlternateScreen,
|
||||
DisableMouseCapture
|
||||
)?;
|
||||
terminal.show_cursor()?;
|
||||
|
||||
if let Err(err) = res {
|
||||
println!("Error: {:?}", err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
157
tui-rust/src/ui.rs
Normal file
157
tui-rust/src/ui.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
use crate::app::{App, AppState, LoginStep};
|
||||
use ratatui::{
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Line, Span},
|
||||
widgets::{Block, Borders, List, ListItem, Paragraph, Wrap},
|
||||
Frame,
|
||||
};
|
||||
|
||||
pub fn draw(frame: &mut Frame, app: &App) {
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Length(3), // Header
|
||||
Constraint::Min(0), // Main content
|
||||
Constraint::Length(3), // Footer/Status
|
||||
])
|
||||
.split(frame.size());
|
||||
|
||||
// Header
|
||||
let header = Paragraph::new("AtlasOS Terminal Interface")
|
||||
.style(Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD))
|
||||
.alignment(Alignment::Center)
|
||||
.block(Block::default().borders(Borders::ALL));
|
||||
frame.render_widget(header, chunks[0]);
|
||||
|
||||
// Main content based on state
|
||||
match &app.state {
|
||||
AppState::Login => draw_login(frame, app, chunks[1]),
|
||||
AppState::MainMenu => draw_main_menu(frame, app, chunks[1]),
|
||||
AppState::ZFSMenu => draw_zfs_menu(frame, app, chunks[1]),
|
||||
AppState::ViewingData => draw_data_view(frame, app, chunks[1]),
|
||||
_ => draw_main_menu(frame, app, chunks[1]),
|
||||
}
|
||||
|
||||
// Footer/Status
|
||||
let footer_text = if app.input_mode {
|
||||
format!("Input: {}", app.input_buffer)
|
||||
} else {
|
||||
"Press 'q' to quit, Enter to select".to_string()
|
||||
};
|
||||
|
||||
let footer = Paragraph::new(footer_text)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.block(Block::default().borders(Borders::ALL));
|
||||
frame.render_widget(footer, chunks[2]);
|
||||
|
||||
// Show error/success messages
|
||||
if let Some(ref error) = app.error_message {
|
||||
let error_block = Paragraph::new(error.as_str())
|
||||
.style(Style::default().fg(Color::Red))
|
||||
.block(Block::default().borders(Borders::ALL).title("Error"));
|
||||
frame.render_widget(error_block, frame.size());
|
||||
}
|
||||
|
||||
if let Some(ref success) = app.success_message {
|
||||
let success_block = Paragraph::new(success.as_str())
|
||||
.style(Style::default().fg(Color::Green))
|
||||
.block(Block::default().borders(Borders::ALL).title("Success"));
|
||||
frame.render_widget(success_block, frame.size());
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_login(frame: &mut Frame, app: &App, area: Rect) {
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Length(3), Constraint::Length(3), Constraint::Min(0)])
|
||||
.split(area);
|
||||
|
||||
let username_prompt = Paragraph::new(if app.login_step == LoginStep::Username {
|
||||
format!("Username: {}", app.input_buffer)
|
||||
} else {
|
||||
format!("Username: {}", app.username)
|
||||
})
|
||||
.block(Block::default().borders(Borders::ALL).title("Login - Username"));
|
||||
frame.render_widget(username_prompt, chunks[0]);
|
||||
|
||||
let password_prompt = Paragraph::new(if app.login_step == LoginStep::Password {
|
||||
format!("Password: {}", "*".repeat(app.input_buffer.len()))
|
||||
} else if app.login_step == LoginStep::Done {
|
||||
"Password: ********".to_string()
|
||||
} else {
|
||||
"Password: ".to_string()
|
||||
})
|
||||
.block(Block::default().borders(Borders::ALL).title("Login - Password"));
|
||||
frame.render_widget(password_prompt, chunks[1]);
|
||||
}
|
||||
|
||||
fn draw_main_menu(frame: &mut Frame, app: &App, area: Rect) {
|
||||
let items = vec![
|
||||
ListItem::new("1. ZFS Management"),
|
||||
ListItem::new("2. Storage Services"),
|
||||
ListItem::new("3. Snapshots"),
|
||||
ListItem::new("4. System Information"),
|
||||
ListItem::new("5. Backup & Restore"),
|
||||
ListItem::new("6. User Management"),
|
||||
ListItem::new("7. Service Management"),
|
||||
ListItem::new("0. Exit"),
|
||||
];
|
||||
|
||||
let list = List::new(items)
|
||||
.block(Block::default().borders(Borders::ALL).title("Main Menu"))
|
||||
.highlight_style(
|
||||
Style::default()
|
||||
.bg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)
|
||||
.highlight_symbol(">> ");
|
||||
|
||||
frame.render_stateful_widget(list, area, &mut app.list_state.clone());
|
||||
}
|
||||
|
||||
fn draw_zfs_menu(frame: &mut Frame, app: &App, area: Rect) {
|
||||
let items = vec![
|
||||
ListItem::new("1. List Pools"),
|
||||
ListItem::new("2. Create Pool"),
|
||||
ListItem::new("3. Delete Pool"),
|
||||
ListItem::new("4. Import Pool"),
|
||||
ListItem::new("5. Export Pool"),
|
||||
ListItem::new("6. List Available Pools"),
|
||||
ListItem::new("7. Start Scrub"),
|
||||
ListItem::new("8. Get Scrub Status"),
|
||||
ListItem::new("9. List Datasets"),
|
||||
ListItem::new("10. Create Dataset"),
|
||||
ListItem::new("11. Delete Dataset"),
|
||||
ListItem::new("12. List ZVOLs"),
|
||||
ListItem::new("13. Create ZVOL"),
|
||||
ListItem::new("14. Delete ZVOL"),
|
||||
ListItem::new("15. List Disks"),
|
||||
ListItem::new("0. Back"),
|
||||
];
|
||||
|
||||
let list = List::new(items)
|
||||
.block(Block::default().borders(Borders::ALL).title("ZFS Management"))
|
||||
.highlight_style(
|
||||
Style::default()
|
||||
.bg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)
|
||||
.highlight_symbol(">> ");
|
||||
|
||||
frame.render_stateful_widget(list, area, &mut app.list_state.clone());
|
||||
}
|
||||
|
||||
fn draw_data_view(frame: &mut Frame, app: &App, area: Rect) {
|
||||
let text = if let Some(ref data) = app.data {
|
||||
serde_json::to_string_pretty(data).unwrap_or_else(|_| "Invalid JSON".to_string())
|
||||
} else {
|
||||
"No data".to_string()
|
||||
};
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(Block::default().borders(Borders::ALL).title("Data"))
|
||||
.wrap(Wrap { trim: true });
|
||||
frame.render_widget(paragraph, area);
|
||||
}
|
||||
|
||||
1
tui-rust/target/.rustc_info.json
Normal file
1
tui-rust/target/.rustc_info.json
Normal file
@@ -0,0 +1 @@
|
||||
{"rustc_fingerprint":2852558656607291690,"outputs":{"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.92.0 (ded5c06cf 2025-12-08)\nbinary: rustc\ncommit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234\ncommit-date: 2025-12-08\nhost: x86_64-unknown-linux-gnu\nrelease: 1.92.0\nLLVM version: 21.1.3\n","stderr":""}},"successes":{}}
|
||||
3
tui-rust/target/CACHEDIR.TAG
Normal file
3
tui-rust/target/CACHEDIR.TAG
Normal file
@@ -0,0 +1,3 @@
|
||||
Signature: 8a477f597d28d172789f06886806bc55
|
||||
# This file is a cache directory tag created by cargo.
|
||||
# For information about cache directory tags see https://bford.info/cachedir/
|
||||
0
tui-rust/target/debug/.cargo-lock
Normal file
0
tui-rust/target/debug/.cargo-lock
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
9f46af916923b818
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"alloc\"]","declared_features":"[\"alloc\", \"default\", \"fresh-rust\", \"nightly\", \"serde\", \"std\"]","target":5388200169723499962,"profile":187265481308423917,"path":10591411839453927008,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/allocator-api2-00a55c07d0ea4ce1/dep-lib-allocator_api2","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
@@ -0,0 +1 @@
|
||||
dc662e630174161b
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[1852463361802237065,"build_script_build",false,7542658676444820174]],"local":[{"RerunIfChanged":{"output":"debug/build/anyhow-7dffd08ca73f1c01/output","paths":["src/nightly.rs"]}},{"RerunIfEnvChanged":{"var":"RUSTC_BOOTSTRAP","val":null}}],"rustflags":[],"config":0,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
9037ebe70e28bb6a
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"default\", \"std\"]","declared_features":"[\"backtrace\", \"default\", \"std\"]","target":16100955855663461252,"profile":2241668132362809309,"path":6508595044157912618,"deps":[[1852463361802237065,"build_script_build",false,1951875037819463388]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/anyhow-a8e29080dfa88f6a/dep-lib-anyhow","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
@@ -0,0 +1 @@
|
||||
cef2827f1ae8ac68
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"default\", \"std\"]","declared_features":"[\"backtrace\", \"default\", \"std\"]","target":17883862002600103897,"profile":2225463790103693989,"path":12383270898441138485,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/anyhow-f0f8ac34947eb6de/dep-build-script-build-script-build","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
674a9fe368f24e7e
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[]","target":734735678962942177,"profile":17672942494452627365,"path":4942398508502643691,"deps":[[1852463361802237065,"anyhow",false,7690784833150859152],[6770350463469152398,"ratatui",false,8605790855636449198],[7720834239451334583,"tokio",false,15912980743490839798],[8256202458064874477,"dirs",false,3269800498822942012],[12832915883349295919,"serde_json",false,16487956888173208731],[13548984313718623784,"serde",false,5329090938770790385],[15232994347474474160,"reqwest",false,15480548085929901409],[17030156879047273469,"crossterm",false,4957819273199307474]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/atlas-tui-942713f2b8879d87/dep-bin-atlas-tui","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
43c815419676b18a
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[\"portable-atomic\"]","target":14411119108718288063,"profile":2241668132362809309,"path":14374989505947797619,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/atomic-waker-5d2db5f7d9229e4e/dep-lib-atomic_waker","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
fbeb557ceabbc941
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"alloc\", \"default\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"std\"]","target":13060062996227388079,"profile":2241668132362809309,"path":16841996087006313610,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/base64-77885587371c3c70/dep-lib-base64","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
399b8e222bd51e75
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"std\"]","declared_features":"[\"arbitrary\", \"bytemuck\", \"example_generated\", \"serde\", \"serde_core\", \"std\"]","target":7691312148208718491,"profile":2241668132362809309,"path":18132948457891314767,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/bitflags-c10f145ac5d2b8b0/dep-lib-bitflags","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
5c467bf1ce00fc07
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"default\", \"std\"]","declared_features":"[\"default\", \"extra-platforms\", \"serde\", \"std\"]","target":11402411492164584411,"profile":13827760451848848284,"path":4272742517227241382,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/bytes-22e51706ccb8b8a5/dep-lib-bytes","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
815964b2d56322bd
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[]","target":10353004457644949388,"profile":2241668132362809309,"path":9079747549669873607,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/cassowary-aa4b64b6516378b9/dep-lib-cassowary","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
acc856170b75e508
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"alloc\", \"default\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"std\"]","target":13710694652376480987,"profile":2241668132362809309,"path":7051727155796915785,"deps":[[14156967978702956262,"rustversion",false,3576039853037520463]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/castaway-ff42463aed60da48/dep-lib-castaway","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
be523ed4acabb160
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[\"jobserver\", \"parallel\"]","target":11042037588551934598,"profile":4333757155065362140,"path":17383320173655230330,"deps":[[3099554076084276815,"find_msvc_tools",false,15966056650687871624],[8410525223747752176,"shlex",false,12430830252493355193]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/cc-5ababa02f409e72c/dep-lib-cc","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
d900adba52e0b576
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[\"core\", \"rustc-dep-of-std\"]","target":13840298032947503755,"profile":2241668132362809309,"path":12502755193429384494,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/cfg-if-e720413b8edafa0a/dep-lib-cfg_if","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
b91f26981adf1a0f
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[\"arbitrary\", \"bytes\", \"markup\", \"proptest\", \"quickcheck\", \"rkyv\", \"serde\", \"smallvec\"]","target":12681387934967326413,"profile":2241668132362809309,"path":16585554804481745583,"deps":[[1127187624154154345,"castaway",false,641047212466817196],[7667230146095136825,"cfg_if",false,8553989713183965401],[13785866025199020095,"static_assertions",false,10291160929660643979],[14468264357544478988,"itoa",false,6186034875721881408],[15688235455146705107,"ryu",false,14470341346598747597]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/compact_str-6352bc54d98381c4/dep-lib-compact_str","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
d24aa17f5cb6cd44
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"bracketed-paste\", \"default\", \"events\", \"windows\"]","declared_features":"[\"bracketed-paste\", \"default\", \"event-stream\", \"events\", \"filedescriptor\", \"libc\", \"serde\", \"use-dev-tty\", \"windows\"]","target":7162149947039624270,"profile":2241668132362809309,"path":4837326999873331563,"deps":[[3430646239657634944,"rustix",false,14217815455417083885],[4627466251042474366,"signal_hook_mio",false,5567887508813209129],[9001817693037665195,"bitflags",false,8439417132978969401],[9156379307790651767,"mio",false,17228512017508346083],[12459942763388630573,"parking_lot",false,1853447893049640521],[17154765528929363175,"signal_hook",false,18380763669658861905]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/crossterm-07436bce45723907/dep-lib-crossterm","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
8d6fb3cc4d6f101a
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"bracketed-paste\", \"default\", \"events\", \"windows\"]","declared_features":"[\"bracketed-paste\", \"default\", \"event-stream\", \"events\", \"filedescriptor\", \"serde\", \"use-dev-tty\", \"windows\"]","target":7162149947039624270,"profile":2241668132362809309,"path":13494933240171638998,"deps":[[4627466251042474366,"signal_hook_mio",false,5567887508813209129],[8730874933663560167,"libc",false,14297221119988602182],[9001817693037665195,"bitflags",false,8439417132978969401],[10703860158168350592,"mio",false,14194003628438370002],[12459942763388630573,"parking_lot",false,1853447893049640521],[17154765528929363175,"signal_hook",false,18380763669658861905]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/crossterm-f5d3f81935b0e066/dep-lib-crossterm","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
3c8dbcc23aaa602d
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[]","target":8852154185408534478,"profile":2241668132362809309,"path":16480735575227115549,"deps":[[11795441179928084356,"dirs_sys",false,18011542114159487803]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/dirs-c5b065c0a7a6fcf3/dep-lib-dirs","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
3beb76a31fdaf5f9
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[]","target":1716570026465204918,"profile":2241668132362809309,"path":2042082684137801100,"deps":[[8730874933663560167,"libc",false,14297221119988602182],[9760035060063614848,"option_ext",false,14281056310037105554]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/dirs-sys-09fc8f284ff83619/dep-lib-dirs_sys","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
fc56741641cece53
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[\"default\", \"std\"]","target":9331843185013996172,"profile":2225463790103693989,"path":9239498791833899309,"deps":[[7988640081342112296,"syn",false,5724889961548129301],[9869581871423326951,"quote",false,3814339587259028799],[14285738760999836560,"proc_macro2",false,8440063262001025109]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/displaydoc-49ed059c4102aa06/dep-lib-displaydoc","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
93f9dfc12d41e0ea
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"std\", \"use_std\"]","declared_features":"[\"default\", \"serde\", \"std\", \"use_std\"]","target":17124342308084364240,"profile":2241668132362809309,"path":9237815631596662082,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/either-d5303fd443e6a93b/dep-lib-either","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
9340a5f53b6a5279
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[\"alloc\", \"default\"]","declared_features":"[\"alloc\", \"any_all_workaround\", \"default\", \"fast-big5-hanzi-encode\", \"fast-gb-hanzi-encode\", \"fast-hangul-encode\", \"fast-hanja-encode\", \"fast-kanji-encode\", \"fast-legacy-encode\", \"less-slow-big5-hanzi-encode\", \"less-slow-gb-hanzi-encode\", \"less-slow-kanji-encode\", \"serde\", \"simd-accel\"]","target":17616512236202378241,"profile":2241668132362809309,"path":3925965713513787057,"deps":[[7667230146095136825,"cfg_if",false,8553989713183965401]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/encoding_rs-e67227d451a5628b/dep-lib-encoding_rs","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
34b23856d98087d3
|
||||
@@ -0,0 +1 @@
|
||||
{"rustc":4758242423518056681,"features":"[]","declared_features":"[]","target":1524667692659508025,"profile":2241668132362809309,"path":12089184285681878692,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/equivalent-9b88d636aa69c8ed/dep-lib-equivalent","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
@@ -0,0 +1 @@
|
||||
887a0398eed392dd
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user