From 81addda9ecd3c93e54cf45ad196627537ea44f11 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Wed, 25 Jan 2023 00:15:54 +0100 Subject: [PATCH] RUST: Continue C <-> Rust bindings + we will handle the config on the rust side of the force --- .vscode/settings.json | 22 ++--- CMakeLists.txt | 1 - inc/liblektor-rs/config.h | 18 ++++ inc/liblektor-rs/queue.h | 2 +- src/main/server.c | 10 +- src/rust/Cargo.toml | 1 + src/rust/lektor_config/Cargo.toml | 13 +++ src/rust/lektor_config/src/config.rs | 139 +++++++++++++++++++++++++++ src/rust/lektor_config/src/lib.rs | 2 + src/rust/lektor_unsafe/Cargo.toml | 3 + src/rust/lektor_unsafe/src/config.rs | 57 +++++++++++ src/rust/lektor_unsafe/src/lib.rs | 1 + 12 files changed, 252 insertions(+), 17 deletions(-) create mode 100644 inc/liblektor-rs/config.h create mode 100644 src/rust/lektor_config/Cargo.toml create mode 100644 src/rust/lektor_config/src/config.rs create mode 100644 src/rust/lektor_config/src/lib.rs create mode 100644 src/rust/lektor_unsafe/src/config.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index f4203265..14c36fbf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,11 @@ { - "settings": { - "ltex.language": "en", - "languageTool.language": "en", - "editor.formatOnSave": true, - "json.format.enable": true, - "rust-analyzer.checkOnSave.command": "clippy", - "rust-analyzer.inlayHints.parameterHints.enable": false, - "rust-analyzer.diagnostics.enable": true, - "rust-analyzer.procMacro.enable": true, - "rust-analyzer.procMacro.attributes.enable": true, - } -} + "ltex.language": "en", + "languageTool.language": "en", + "editor.formatOnSave": true, + "json.format.enable": true, + "rust-analyzer.checkOnSave.command": "clippy", + "rust-analyzer.inlayHints.parameterHints.enable": false, + "rust-analyzer.diagnostics.enable": true, + "rust-analyzer.procMacro.enable": true, + "rust-analyzer.procMacro.attributes.enable": true, +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 725a16d6..54974088 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,7 +187,6 @@ set(lektor_db_SOURCES set(lektor_module_SOURCES src/base/reg.c - src/module/module_repo.c src/module/module_repo_rs.c src/module/mpv.c src/module/thread.c diff --git a/inc/liblektor-rs/config.h b/inc/liblektor-rs/config.h new file mode 100644 index 00000000..61c5840b --- /dev/null +++ b/inc/liblektor-rs/config.h @@ -0,0 +1,18 @@ + +#if !defined(LIBLEKTOR_RS_DATABASE___) +#define LIBLEKTOR_RS_DATABASE___ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <stdint.h> + +bool lkt_config_write_default_to_file(const char *); +bool lkt_config_write_default_to_default_file(void); + +#if defined(__cplusplus) +} +#endif + +#endif // LIBLEKTOR_RS_DATABASE___ diff --git a/inc/liblektor-rs/queue.h b/inc/liblektor-rs/queue.h index 8d32c302..48f0abe8 100644 --- a/inc/liblektor-rs/queue.h +++ b/inc/liblektor-rs/queue.h @@ -22,7 +22,7 @@ typedef struct lkt_database_queue lkt_database_queue; */ typedef void (*lkt_search_cb)(int64_t, void *restrict); -lkt_database_queue *lkt_database_queue_new(); +lkt_database_queue *lkt_database_queue_new(void); void lkt_database_queue_delete(lkt_database_queue *); bool lkt_database_queue_current(lkt_database_queue *, int64_t *restrict); diff --git a/src/main/server.c b/src/main/server.c index 865cdea4..44ebedd4 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -9,8 +9,10 @@ #include <lektor/launch.h> #include <lektor/logfile.h> -#include <liblektor-rs/database.h> #include <liblektor-rs/loging.h> +#include <liblektor-rs/config.h> +#include <liblektor-rs/database.h> +#include <liblektor-rs/queue.h> #include <wait.h> #include <spawn.h> @@ -20,7 +22,6 @@ #if defined(LKT_STATIC_MODULE) REG_DECLARE(qt_window_reg) -REG_DECLARE(repo_reg) REG_DECLARE(repo_rs_reg) #endif @@ -42,7 +43,6 @@ main(int argc, char *argv[]) REG_ADD(database_upgrade_scheme) #if defined(LKT_STATIC_MODULE) REG_REGISTER("repo_rs", repo_rs_reg) - REG_REGISTER("repo", repo_reg) REG_REGISTER("qt", qt_window_reg) #endif REG_END() @@ -92,6 +92,7 @@ main(int argc, char *argv[]) FAIL_IF(lkt_queue_new(&srv.queue), "Failed to create server queue"); FAIL_UNLESS(database_new(&srv.db), "Failed to init memory database"); FAIL_IF(config_open(srv.db, conf_file, PATH_MAX), "Failed to open or create the config file"); + lkt_config_write_default_to_default_file(); /* Dump and abort here, if we are dumping informations about the server */ if (dump_and_abort) { @@ -108,6 +109,9 @@ main(int argc, char *argv[]) lkt_set_log_logfile(logfile); lektor_init_rust_logging(); + /* Create objects from the rust part of the code */ + lkt_database_queue *const UNUSED queue = lkt_database_queue_new(); + /* Read the configuration. We already know that the config is valid */ database_config_get_int(srv.db, "player", "autoclear", &autoclear); database_config_get_text(srv.db, "database", "kara_dir", kara_dir, PATH_MAX); diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 80ffe6fa..fd3c5609 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -6,6 +6,7 @@ members = [ "lektor_db", "lektor_repo", "lektor_unsafe", + "lektor_config", # Common things "kurisu_api", diff --git a/src/rust/lektor_config/Cargo.toml b/src/rust/lektor_config/Cargo.toml new file mode 100644 index 00000000..92cbcd10 --- /dev/null +++ b/src/rust/lektor_config/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "lektor_config" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true + +[dependencies] +log.workspace = true +serde.workspace = true +thiserror.workspace = true + +lektor_c_compat = { path = "../lektor_c_compat" } diff --git a/src/rust/lektor_config/src/config.rs b/src/rust/lektor_config/src/config.rs new file mode 100644 index 00000000..43b01cc6 --- /dev/null +++ b/src/rust/lektor_config/src/config.rs @@ -0,0 +1,139 @@ +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +#[derive(Debug, Serialize, Deserialize)] +pub enum RepoApiVersion { + V1, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum LogLevel { + #[serde(rename = "DEBUG")] + Debug, + + #[serde(rename = "INFO")] + Info, + + #[serde(rename = "WARN")] + Warn, + + #[serde(rename = "ERROR")] + Error, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct LektorConfig { + pub log: LektorLogConfig, + pub database: LektorDatabaseConfig, + pub player: LektorPlayerConfig, + pub repo: LektorRepoConfig, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct LektorLogConfig { + pub level: LogLevel, + pub folder: PathBuf, + pub file_count: u64, + pub line_count: u64, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct LektorDatabaseConfig { + pub kara_dir: PathBuf, + pub dir_permission: u64, + pub db_path: PathBuf, + pub autoclear_queue: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct LektorPlayerConfig { + pub module: String, + pub fond_size: u64, + pub font_name: String, + pub msg_duration: u64, + pub force_x11: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct LektorRepoConfig { + pub module: String, + pub workers: usize, + pub server: Vec<RepoConfig>, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct RepoConfig { + pub name: String, + pub api: RepoApiVersion, + pub urls: Vec<String>, +} + +impl Default for LogLevel { + fn default() -> Self { + LogLevel::Debug + } +} + +impl Default for LektorLogConfig { + fn default() -> Self { + Self { + level: Default::default(), + folder: PathBuf::from("/home/kara/logs"), + file_count: 10, + line_count: 1000, + } + } +} + +impl Default for LektorDatabaseConfig { + fn default() -> Self { + Self { + kara_dir: PathBuf::from("/home/kara"), + dir_permission: 0o700, + db_path: PathBuf::from("/home/kara/lektor.db"), + autoclear_queue: true, + } + } +} + +impl Default for LektorPlayerConfig { + fn default() -> Self { + Self { + module: String::from("qt"), + fond_size: 12, + font_name: String::from("monospace"), + msg_duration: 4, + force_x11: true, + } + } +} + +impl Default for LektorRepoConfig { + fn default() -> Self { + Self { + module: String::from("repo_rs"), + workers: 2, + server: vec![ + Default::default(), + RepoConfig { + name: String::from("Dummy"), + api: RepoApiVersion::V1, + urls: Default::default(), + }, + ], + } + } +} + +impl Default for RepoConfig { + fn default() -> Self { + Self { + name: String::from("Kurisu"), + api: RepoApiVersion::V1, + urls: vec![ + String::from("https://kurisu.iiens.net/api"), + String::from("http://kurisu.iiens.net/api"), + ], + } + } +} diff --git a/src/rust/lektor_config/src/lib.rs b/src/rust/lektor_config/src/lib.rs new file mode 100644 index 00000000..12f374cf --- /dev/null +++ b/src/rust/lektor_config/src/lib.rs @@ -0,0 +1,2 @@ +mod config; +pub use config::*; diff --git a/src/rust/lektor_unsafe/Cargo.toml b/src/rust/lektor_unsafe/Cargo.toml index 5bbff867..8aae3c2f 100644 --- a/src/rust/lektor_unsafe/Cargo.toml +++ b/src/rust/lektor_unsafe/Cargo.toml @@ -8,8 +8,11 @@ crate-type = ["staticlib"] [dependencies] log.workspace = true +toml.workspace = true lazy_static.workspace = true lektor_c_compat = { path = "../lektor_c_compat", features = ["c_types"] } +lektor_config = { path = "../lektor_config" } lektor_repo = { path = "../lektor_repo" } lektor_db = { path = "../lektor_db" } +commons = { path = "../commons" } diff --git a/src/rust/lektor_unsafe/src/config.rs b/src/rust/lektor_unsafe/src/config.rs new file mode 100644 index 00000000..0d83938a --- /dev/null +++ b/src/rust/lektor_unsafe/src/config.rs @@ -0,0 +1,57 @@ +//! An unsafe interface around the rust implementation of the config read/write +//! things to be able to call it from C or C++ code. +//! +//! Be carefull when naming things because those names might collide with things +//! defined in lektor's C code... + +use crate::*; +use lektor_config::*; + +#[no_mangle] +pub unsafe extern "C" fn lkt_config_write_default_to_file(file: *const u8) -> bool { + let mut len = 0; + while *file.offset(len) != 0 { + len += 1 + } + let file = ManuallyDrop::new(String::from_raw_parts( + file as *mut _, + len as usize, + len as usize, + )); + + let conf = match toml::to_string_pretty(&LektorConfig::default()) { + Ok(conf) => conf, + Err(err) => { + log::error!(target: "CONF", "failed to serialize default config: {err}"); + return false; + } + }; + + match std::fs::write(PathBuf::from(&file[..]), conf) { + Ok(()) => true, + Err(err) => { + log::error!(target: "CONF", "failed to write default config to {}: {err}", &file[..]); + false + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn lkt_config_write_default_to_default_file() -> bool { + let path = commons::user_config_directory("lektor").join("lektor.toml"); + let conf = match toml::to_string_pretty(&LektorConfig::default()) { + Ok(conf) => conf, + Err(err) => { + log::error!(target: "CONF", "failed to serialize default config: {err}"); + return false; + } + }; + + match std::fs::write(&path, conf) { + Ok(()) => true, + Err(err) => { + log::error!(target: "CONF", "failed to write default config to {}: {err}", path.to_string_lossy()); + false + } + } +} diff --git a/src/rust/lektor_unsafe/src/lib.rs b/src/rust/lektor_unsafe/src/lib.rs index 39a589fe..476ce351 100644 --- a/src/rust/lektor_unsafe/src/lib.rs +++ b/src/rust/lektor_unsafe/src/lib.rs @@ -1,6 +1,7 @@ //! Create C functions to calls things defined in the rust language from C code. //! See the headers inside the liblektor-rs folder from the C include directory. +pub mod config; pub mod db; pub mod loging; pub mod queue; -- GitLab