This repository has been archived on 2026-08-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
el-retired/ide/vessels/el-ide-server/src/api/status.rs
T
Will Anderson be013d2b42 rename crates/ → vessels/ — El's word for buildable units
Per the consolidation onto El: 'crates' is the Rust word, 'vessel' is
El's (per spec/language.md §15). The directory rename is the structural
marker that this slot holds an El buildable unit, even if its current
contents are still Rust pending port.

Mechanical: git mv crates vessels, sed workspace members and any path
dependencies, update CI workflow paths, update README references.
Cross-repo path dependencies (`../foo/crates/bar`) updated workspace-
wide so cargo metadata still resolves where the Rust still builds.
2026-04-30 15:34:20 -05:00

95 lines
2.5 KiB
Rust

//! Status API — project metadata and server health.
use std::path::{Path, PathBuf};
use axum::{extract::State, Json};
use serde::Serialize;
use crate::AppState;
#[derive(Debug, Serialize)]
pub struct StatusResponse {
pub project_name: String,
pub project_path: String,
pub file_count: usize,
pub el_file_count: usize,
pub version: String,
pub el_version: Option<String>,
}
/// GET /api/status
pub async fn status(State(state): State<AppState>) -> Json<StatusResponse> {
let project_path = state.config.project_path.clone();
let root = PathBuf::from(&project_path);
let project_name = root
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_else(|| project_path.clone());
let (file_count, el_file_count) = count_files(&root);
let el_version = get_el_version(&state.config.el_binary);
Json(StatusResponse {
project_name,
project_path,
file_count,
el_file_count,
version: "0.1.0".into(),
el_version,
})
}
fn get_el_version(binary: &str) -> Option<String> {
let out = std::process::Command::new(binary)
.arg("--version")
.output()
.ok()?;
let text = String::from_utf8_lossy(&out.stdout).to_string();
let text = text.trim();
if text.is_empty() {
let err = String::from_utf8_lossy(&out.stderr).to_string();
let err = err.trim().to_string();
if err.is_empty() { None } else { Some(err) }
} else {
Some(text.to_string())
}
}
fn should_skip_dir(name: &str) -> bool {
matches!(name, "target" | ".git" | "node_modules" | "dist" | ".cargo")
}
fn count_files(root: &Path) -> (usize, usize) {
let mut total = 0usize;
let mut el_count = 0usize;
count_files_recursive(root, &mut total, &mut el_count);
(total, el_count)
}
fn count_files_recursive(dir: &Path, total: &mut usize, el_count: &mut usize) {
let rd = match std::fs::read_dir(dir) {
Ok(r) => r,
Err(_) => return,
};
for entry in rd.filter_map(|e| e.ok()) {
let path = entry.path();
let name = entry.file_name().to_string_lossy().to_string();
if name.starts_with('.') {
continue;
}
if path.is_dir() {
if should_skip_dir(&name) {
continue;
}
count_files_recursive(&path, total, el_count);
} else {
*total += 1;
if name.ends_with(".el") {
*el_count += 1;
}
}
}
}