···11#!/usr/bin/env bash
22set -euo pipefail
3344-ENV="prod" # prod is another env, try taking it from github env
44+ENV="dev" # prod is another env, try taking it from github env
55REPO="tilesprivacy/tiles"
66# VERSION="${TILES_VERSION:-latest}"
77VERSION="0.4.1"
+253-7
tiles/src/commands/mod.rs
···11// Module that handles CLI commands
2233-use anyhow::Result;
33+use std::io;
44+55+use anyhow::{Result, anyhow};
46use owo_colors::OwoColorize;
57use tiles::runtime::Runtime;
68use tiles::utils::accounts::{
79 RootUser, create_root_account, get_root_user_details, save_root_account, set_nickname,
810};
99-use tiles::utils::config::{get_or_create_config, set_memory_path};
1111+use tiles::utils::config::{
1212+ ConfigProvider, DefaultProvider, get_or_create_config, set_user_data_path,
1313+};
1014use tiles::{core::health, runtime::RunArgs};
11151616+use tilekit::modelfile::parse_from_file;
1217pub use tilekit::optimize::optimize;
1818+use toml::Table;
13191420use crate::{AccountArgs, AccountCommands};
15212222+const FTUE_VERSION_TITLE: &str = "Tiles v0.4.1";
2323+const FTUE_HEADER: &str = "Initializing local account...";
2424+const FTUE_ASCII_ART: &str = r#"
2525+ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
2626+ ▓▓ ▓▓░░▓▒
2727+ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓
2828+ ▓▓░░░░░░░▓▓░ ▓▓▓░░░░░▓▓ ▓▓
2929+ ▓▓ ░▓▒ ▓▓ ▓▒ ▒▓░▓▓
3030+ ▓▓▓▓▓▓▓▒ ▓▓ ▓▓▓▓▓▓▓▓▓▓
3131+ ▓▓ ▓▓ ░▓░
3232+ ▓▓ ▒▓░ ▓▒
3333+ ▒▓ ░▓░ ▓▓
3434+ ▒▓ ░▓▒ ▓▓
3535+ ░▓░ ▓▓ ▓▓
3636+ ░▓▒ ▓▓ ▒▓
3737+ ▓▓▓▓▓▓▓▓ ▒▓░
3838+ ░▓▒ ▓▓ ░▓░
3939+ ▓▓ ▓▓▓▒
4040+ ▓▓▓▓▓▓▓▓
4141+"#;
4242+const FTUE_REASSURANCE_LOCAL: &str = "On-device by default.";
4343+const FTUE_REASSURANCE_NO_CLOUD: &str = "Online models and identity optional.";
4444+const FTUE_NICKNAME_PROMPT: &str = "Choose a username:";
4545+const FTUE_NICKNAME_REQUIRED: &str = "Username is required. Please enter a username:";
4646+const FTUE_ACCOUNT_CREATED: &str = "✓ Account created";
4747+const FTUE_ACCOUNT_LABEL: &str = "Account";
4848+const FTUE_ACCOUNT_DETAILS_HINT: &str = "View full details:";
4949+const FTUE_ACCOUNT_DETAILS_COMMAND: &str = "tiles account";
5050+const FTUE_DATA_DIR_PROMPT: &str = "Data directory";
5151+const FTUE_DATA_DIR_CHANGE_HINT: &str = "Change data path later:";
5252+const FTUE_DATA_DIR_CHANGE_COMMAND: &str = "tiles data set-path <PATH>";
5353+const FTUE_CUSTOM_DATA_PROMPT: &str = "Use a custom data directory now? [y/N]";
5454+5555+pub fn run_setup_for_ftue(run_args: &RunArgs) -> Result<()> {
5656+ // initializes config directory
5757+ let config_provider = DefaultProvider;
5858+ config_provider.get_or_create_config_dir()?;
5959+ config_provider.get_or_create_data_dir()?;
6060+6161+ let root_config = get_or_create_config()?;
6262+ let root_user_details = get_root_user_details(&root_config)?;
6363+ println!("{}", FTUE_ASCII_ART.blue());
6464+ println!("{}", FTUE_VERSION_TITLE);
6565+ println!();
6666+6767+ if root_user_details.id.is_empty() {
6868+ println!("{}", FTUE_HEADER);
6969+ println!();
7070+ println!("{}", FTUE_REASSURANCE_LOCAL);
7171+ println!("{}", FTUE_REASSURANCE_NO_CLOUD);
7272+ println!();
7373+ // FTUE
7474+ setup_root_account(root_config.clone())?;
7575+ setup_default_user_data_dir(&config_provider)?
7676+ } else {
7777+ print_runtime_context(run_args, &config_provider, &root_user_details)?;
7878+ }
7979+8080+ Ok(())
8181+}
8282+8383+fn print_runtime_context<T: ConfigProvider>(
8484+ run_args: &RunArgs,
8585+ config_provider: &T,
8686+ root_user_details: &RootUser,
8787+) -> Result<()> {
8888+ let model_name = get_configured_model_name(run_args.memory, config_provider)?;
8989+ let directory = config_provider
9090+ .get_user_data_dir()
9191+ .map(|path| path.display().to_string())?;
9292+9393+ let nickname = if root_user_details.nickname.is_empty() {
9494+ "Unknown"
9595+ } else {
9696+ root_user_details.nickname.as_str()
9797+ };
9898+9999+ println!("Account:");
100100+ println!(" {} (DID: {})", nickname, root_user_details.id);
101101+ println!("Model:");
102102+ println!(" {}", model_name);
103103+ println!("Directory:");
104104+ println!(" {}", directory);
105105+ println!();
106106+ Ok(())
107107+}
108108+109109+fn get_configured_model_name<T: ConfigProvider>(
110110+ memory_mode: bool,
111111+ config_provider: &T,
112112+) -> Result<String> {
113113+ let modelfile_path = if memory_mode {
114114+ config_provider.get_lib_dir()?.join("modelfiles/mem-agent")
115115+ } else {
116116+ config_provider.get_lib_dir()?.join("modelfiles/gpt-oss")
117117+ };
118118+119119+ let modelfile_path_str = modelfile_path
120120+ .to_str()
121121+ .ok_or_else(|| anyhow!("Failed to parse modelfile path"))?;
122122+ let modelfile = parse_from_file(modelfile_path_str)
123123+ .map_err(|err| anyhow!("Failed to parse modelfile: {}", err))?;
124124+ modelfile
125125+ .from
126126+ .ok_or_else(|| anyhow!("Missing FROM in modelfile {}", modelfile_path.display()))
127127+}
128128+129129+fn setup_root_account(root_config: Table) -> Result<()> {
130130+ println!("{}", FTUE_NICKNAME_PROMPT);
131131+ let nickname = read_required_nickname()?;
132132+ let root_user_config = RootUser::new(&create_root_account(&root_config, Some(nickname))?)?;
133133+134134+ save_root_account(root_config, &root_user_config.to_table())?;
135135+ println!();
136136+ println!("{}", FTUE_ACCOUNT_CREATED);
137137+ println!();
138138+ println!("{}", FTUE_ACCOUNT_LABEL);
139139+ println!(" Nickname: {}", root_user_config.nickname);
140140+ println!(" DID: {}", root_user_config.id);
141141+ println!("{}", FTUE_ACCOUNT_DETAILS_HINT);
142142+ println!(" {}", FTUE_ACCOUNT_DETAILS_COMMAND.bright_blue().bold());
143143+ println!();
144144+ Ok(())
145145+}
146146+147147+fn setup_default_user_data_dir<T: ConfigProvider>(config_provider: &T) -> Result<()> {
148148+ // gets default data dir -> ~/.local/share/tiles/data
149149+ // shows this is the data dir
150150+ // asks if they want to change, if y, asks for new loc, else keep current one
151151+ // writes the default/new path to in config.toml data->path
152152+ //
153153+ let user_data_dir = config_provider.get_user_data_dir()?;
154154+ println!("{}", FTUE_DATA_DIR_PROMPT);
155155+ println!(" {}", user_data_dir.display());
156156+ println!();
157157+ println!("{}", FTUE_DATA_DIR_CHANGE_HINT);
158158+ println!(" {}", FTUE_DATA_DIR_CHANGE_COMMAND.bright_blue().bold());
159159+ println!();
160160+ println!("{}", FTUE_CUSTOM_DATA_PROMPT);
161161+162162+ let stdin = io::stdin();
163163+ let mut input = String::new();
164164+ loop {
165165+ input.clear();
166166+ stdin.read_line(&mut input)?;
167167+ let choice = input.trim().to_lowercase();
168168+169169+ if choice.is_empty() || choice == "n" {
170170+ match set_user_data_path(
171171+ user_data_dir
172172+ .to_str()
173173+ .ok_or_else(|| anyhow!("Failed to parse user data dir"))?,
174174+ ) {
175175+ Ok(_msg) => return Ok(()),
176176+ Err(err) => {
177177+ let error_msg = format!("Error setting user data path due to {:?}", err);
178178+ println!("{}", error_msg.red());
179179+ return Err(anyhow::anyhow!("Error setting default user data path"));
180180+ }
181181+ }
182182+ }
183183+184184+ if choice == "y" {
185185+ println!("Enter custom data path:");
186186+ input.clear();
187187+ stdin.read_line(&mut input)?;
188188+ let custom_path = input.trim();
189189+ if custom_path.is_empty() {
190190+ println!("{}", "Path is required. Try again.".red());
191191+ continue;
192192+ }
193193+194194+ match set_user_data_path(custom_path) {
195195+ Ok(msg) => {
196196+ println!("{}", msg.green());
197197+ return Ok(());
198198+ }
199199+ Err(err) => {
200200+ let error_msg = format!("Try again, error setting user data path: {:?}", err);
201201+ println!("{}", error_msg.red());
202202+ continue;
203203+ }
204204+ }
205205+ }
206206+207207+ println!(
208208+ "{}",
209209+ "Please enter y or n (or press Enter for default N).".red()
210210+ );
211211+ }
212212+}
213213+214214+fn read_required_nickname() -> Result<String> {
215215+ let stdin = io::stdin();
216216+ let mut input = String::new();
217217+ loop {
218218+ input.clear();
219219+ stdin.read_line(&mut input)?;
220220+ let nickname = input.trim();
221221+ if nickname.is_empty() {
222222+ println!("{}", FTUE_NICKNAME_REQUIRED);
223223+ continue;
224224+ }
225225+ return Ok(nickname.to_owned());
226226+ }
227227+}
228228+16229pub async fn run(runtime: &Runtime, run_args: RunArgs) {
17230 let _ = runtime.run(run_args).await;
18231}
192322020-pub fn set_memory(path: &str) {
2121- match set_memory_path(path) {
233233+pub fn set_data(path: &str) {
234234+ match set_user_data_path(path) {
22235 Ok(msg) => {
23236 println!("{}", msg.green());
24237 }
···47260 match account_args.command {
48261 Some(AccountCommands::Create { nickname }) => {
49262 if !root_user_details.id.is_empty() {
5050- println!("Root account exists with id: {}", root_user_details.id)
263263+ println!("Local Identity exists with id: {}", root_user_details.id)
51264 } else {
52265 let root_user_config = RootUser::new(&create_root_account(&config, nickname)?)?;
53266···55268 println!(
56269 "{}",
57270 format_args!(
5858- "Root account has been created with id: {}",
271271+ "Local Identity has been created with id: {}",
59272 root_user_config.id
60273 )
61274 )
···9230593306fn get_account_not_created_msg() -> String {
94307 format!(
9595- "Root account not created yet, use {}",
308308+ "Local Identity not created yet, use {}",
96309 "tiles account create".yellow()
97310 )
98311}
312312+313313+#[cfg(test)]
314314+mod tests {
315315+ use super::*;
316316+317317+ #[test]
318318+ fn ftue_copy_matches_expected_constants() {
319319+ assert_eq!(FTUE_VERSION_TITLE, "Tiles v0.4.1");
320320+ assert_eq!(FTUE_HEADER, "Initializing local account...");
321321+ assert_eq!(FTUE_REASSURANCE_LOCAL, "On-device by default.");
322322+ assert_eq!(
323323+ FTUE_REASSURANCE_NO_CLOUD,
324324+ "Online models and identity optional."
325325+ );
326326+ assert_eq!(FTUE_NICKNAME_PROMPT, "Choose a username:");
327327+ assert_eq!(FTUE_ACCOUNT_LABEL, "Account");
328328+ assert_eq!(FTUE_ACCOUNT_DETAILS_HINT, "View full details:");
329329+ assert_eq!(FTUE_DATA_DIR_PROMPT, "Data directory");
330330+ assert_eq!(FTUE_DATA_DIR_CHANGE_HINT, "Change data path later:");
331331+ assert_eq!(
332332+ FTUE_CUSTOM_DATA_PROMPT,
333333+ "Use a custom data directory now? [y/N]"
334334+ );
335335+ }
336336+337337+ #[test]
338338+ fn nickname_required_copy_matches_expected_constant() {
339339+ assert_eq!(
340340+ FTUE_NICKNAME_REQUIRED,
341341+ "Username is required. Please enter a username:"
342342+ );
343343+ }
344344+}
+10-8
tiles/src/main.rs
···2525 flags: RunFlags,
2626 },
27272828- /// Configure your memory
2929- Memory(MemoryArgs),
2828+ /// Configure your data
2929+ Data(DataArgs),
30303131 /// Checks the status of dependencies
3232 Health,
···8585#[derive(Debug, Args)]
8686#[command(args_conflicts_with_subcommands = true)]
8787#[command(flatten_help = true)]
8888-struct MemoryArgs {
8888+struct DataArgs {
8989 #[command(subcommand)]
9090- command: MemoryCommands,
9090+ command: DataCommands,
9191}
9292#[derive(Debug, Subcommand)]
9393-enum MemoryCommands {
9494- /// Set Path for the memory
9393+enum DataCommands {
9494+ /// Set Path for the user data
9595 SetPath { path: String },
9696}
9797···124124 relay_count: cli.flags.relay_count,
125125 memory: cli.flags.memory,
126126 };
127127+ commands::run_setup_for_ftue(&run_args)
128128+ .inspect_err(|e| eprintln!("Failed to setup Tiles due to {:?}", e))?;
127129 commands::run(&runtime, run_args).await;
128130 }
129131 Some(Commands::Run {
···145147 Some(ServerCommands::Stop) => commands::stop_server(&runtime).await,
146148 _ => println!("Expected start or stop"),
147149 },
148148- Some(Commands::Memory(memory)) => match memory.command {
149149- MemoryCommands::SetPath { path } => commands::set_memory(path.as_str()),
150150+ Some(Commands::Data(data)) => match data.command {
151151+ DataCommands::SetPath { path } => commands::set_data(path.as_str()),
150152 },
151153 Some(Commands::Optimize {
152154 modelfile_path,
+12-89
tiles/src/runtime/mlx.rs
···11use crate::runtime::RunArgs;
22-use crate::utils::config::{
33- ConfigProvider, DefaultProvider, create_default_memory_folder, get_default_memory_path,
44- get_memory_path, set_memory_path,
55-};
22+use crate::utils::config::{ConfigProvider, DefaultProvider, get_memory_path};
63use crate::utils::hf_model_downloader::*;
74use anyhow::{Context, Result};
85use futures_util::StreamExt;
···1613use rustyline::{Config, Editor, Helper};
1714use serde::{Deserialize, Serialize};
1815use serde_json::{Value, json};
1919-use std::fs;
2020-use std::fs::File;
1616+use std::fs::OpenOptions;
2117use std::path::PathBuf;
1818+use std::process::Command;
2219use std::process::Stdio;
2320use std::time::Duration;
2424-use std::{io, process::Command};
2521use tilekit::modelfile::Modelfile;
2622use tokio::time::sleep;
2723···10197 }
1029810399 let config_dir = DefaultProvider.get_config_dir()?;
100100+ let data_dir = DefaultProvider.get_data_dir()?;
104101 let mut server_dir = DefaultProvider.get_lib_dir()?;
105102 let pid_file = config_dir.join("server.pid");
106106- fs::create_dir_all(&config_dir).context("Failed to create config directory")?;
107103 server_dir = server_dir.join("server");
108108- let stdout_log = File::create(config_dir.join("server.out.log"))?;
109109- let stderr_log = File::create(config_dir.join("server.err.log"))?;
104104+ let stdout_log = OpenOptions::new()
105105+ .append(true)
106106+ .open(data_dir.join("logs/server.out.log"))?;
107107+ let stderr_log = OpenOptions::new()
108108+ .append(true)
109109+ .open(data_dir.join("logs/server.err.log"))?;
110110 let server_path = server_dir.join("stack_export_prod/app-server/bin/python");
111111 server_dir.pop();
112112 let child = Command::new(server_path)
···203203}
204204205205fn show_help(model_name: &str) {
206206- println!("\n=== Tiles REPL ===\n");
207207-208208- println!("Model:");
209209- println!(" {}", model_name);
210210-211211- println!("Directory:");
212212- println!(" {}\n", get_memory_path().unwrap());
206206+ let _ = model_name;
213207214208 println!("Available Commands:");
215209 println!(" /help Show this help message");
···235229 let _ = wait_until_server_is_up().await;
236230 }
237231 // loading the model from mem-agent via daemon server
238238- let memory_path = get_or_set_memory_path().context("Setting/Retrieving memory_path failed")?;
232232+ let memory_path = get_memory_path().context("Setting/Retrieving memory_path failed")?;
239233 let modelname = modelfile.from.as_ref().unwrap();
240234 match load_model(&modelfile, &default_modelfile, &memory_path).await {
241235 Ok(_) => start_repl(mlx_runtime, modelname, run_args).await,
242236 Err(err) => return Err(anyhow::anyhow!(err)),
243237 }
244238 Ok(())
245245-}
246246-247247-fn get_or_set_memory_path() -> Result<String> {
248248- match get_memory_path() {
249249- Ok(memory_path) => Ok(memory_path),
250250- Err(_err) => {
251251- let stdin = io::stdin();
252252- let default_memory_pathbuf = get_default_memory_path()?;
253253- let mut default_memory = default_memory_pathbuf
254254- .to_str()
255255- .ok_or_else(|| anyhow::anyhow!("Invalid path"))?;
256256- let mut chose_yes = false;
257257-258258- println!(
259259- "{}",
260260- format!(
261261- "Default Memory location will be set at {:?}\n",
262262- default_memory
263263- )
264264- .yellow()
265265- );
266266- println!("You can always change the location with `tiles memory set-path <PATH>`\n");
267267- println!("Do you want to add a custom memory location right now instead? [Y/N]");
268268- let mut input = String::new();
269269- loop {
270270- input.clear();
271271- stdin.read_line(&mut input)?;
272272- input = input.trim().to_owned();
273273- if (input == "Y" || input == "y") || chose_yes {
274274- if !chose_yes {
275275- chose_yes = true;
276276- println!("Add the path for your custom memory");
277277- continue;
278278- }
279279- match set_memory_path(input.as_str()) {
280280- Ok(msg) => {
281281- default_memory = input.as_str();
282282- println!("{}", msg.green());
283283- println!(
284284- "You can always change the location with `tiles memory set-path <PATH>`\n"
285285- );
286286- break;
287287- }
288288- Err(err) => {
289289- let error_msg =
290290- format!("Try again, Error setting memory path due to {:?}", err);
291291- println!("{}", error_msg.red());
292292- continue;
293293- }
294294- }
295295- } else {
296296- create_default_memory_folder()?;
297297- match set_memory_path(default_memory) {
298298- Ok(msg) => {
299299- println!("{}", msg.green());
300300- println!(
301301- "You can always change the location with `tiles memory set-path <PATH>`\n"
302302- );
303303- break;
304304- }
305305- Err(err) => {
306306- let error_msg = format!("Error setting memory path due to {:?}", err);
307307- println!("{}", error_msg.red());
308308- return Err(anyhow::anyhow!("Error setting default memory path"));
309309- }
310310- }
311311- }
312312- }
313313- Ok(default_memory.to_owned())
314314- }
315315- }
316239}
317240318241async fn start_repl(mlx_runtime: &MLXRuntime, modelname: &str, run_args: &RunArgs) {
+76-22
tiles/src/utils/config.rs
···11-// Configuration related stuff
22-11+/// All things configurations in Tiles
22+///
33+/// Tiles by default stores different type of data in 3 folders
44+///
55+/// - ~/.config/tiles (config dir) - Ofcourse the App configs
66+/// - config.toml
77+/// - server.pid - current server daemon pid
88+/// - ~/.local/share/tiles (data dir) - The User generated data should go here + app logs
99+/// - /logs
1010+/// - /data (default, user can change this location tho)
1111+/// - /memory (memory stored as PKM)
1212+/// - ~/.local/lib/tiles (lib dir) - Some internal App files, libraries etc go here..
1313+/// - /modelfiles
1414+/// - /server
315use anyhow::{Context, Result, anyhow};
1616+use std::fs::File;
417use std::path::PathBuf;
518use std::str::FromStr;
619use std::{env, fs};
···821922pub trait ConfigProvider {
1023 fn get_config_dir(&self) -> Result<PathBuf>;
2424+ fn get_or_create_config_dir(&self) -> Result<PathBuf>;
1125 fn get_data_dir(&self) -> Result<PathBuf>;
2626+ fn get_or_create_data_dir(&self) -> Result<PathBuf>;
2727+ fn get_user_data_dir(&self) -> Result<PathBuf>;
1228 fn get_lib_dir(&self) -> Result<PathBuf>;
1329}
1430···3046 }
3147 }
32484949+ fn get_or_create_config_dir(&self) -> Result<PathBuf> {
5050+ let config_dir = self.get_config_dir()?;
5151+ if !config_dir.exists() {
5252+ fs::create_dir_all(&config_dir).context("Failed to create config directory")?;
5353+ }
5454+5555+ Ok(config_dir)
5656+ }
5757+3358 fn get_data_dir(&self) -> Result<PathBuf> {
3459 if cfg!(debug_assertions) {
3560 let base_dir = env::current_dir().context("Failed to fetch CURRENT_DIR")?;
···4469 }
4570 }
46717272+ fn get_or_create_data_dir(&self) -> Result<PathBuf> {
7373+ let data_dir = self.get_data_dir()?;
7474+ if !data_dir.exists() {
7575+ fs::create_dir_all(&data_dir).context("Failed to create data directory")?;
7676+ }
7777+7878+ if !data_dir.join("logs").exists() {
7979+ fs::create_dir(data_dir.join("logs"))?;
8080+ File::create(data_dir.join("logs/server.out.log"))?;
8181+ File::create(data_dir.join("logs/server.err.log"))?;
8282+ }
8383+8484+ if !data_dir.join("data").exists() {
8585+ fs::create_dir_all(data_dir.join("data/memory"))?;
8686+ }
8787+ Ok(data_dir)
8888+ }
8989+9090+ fn get_user_data_dir(&self) -> Result<PathBuf> {
9191+ let data_dir = self.get_data_dir()?;
9292+ Ok(data_dir.join("data"))
9393+ }
9494+4795 fn get_lib_dir(&self) -> Result<PathBuf> {
4896 if cfg!(debug_assertions) {
4997 let base_dir = env::current_dir().context("Failed to fetch CURRENT_DIR")?;
···55103 }
56104 }
57105}
5858-pub fn set_memory_path(path: &str) -> Result<String> {
5959- set_memory_path_with_provider(&DefaultProvider, path)
106106+pub fn set_user_data_path(path: &str) -> Result<String> {
107107+ set_user_data_path_with_provider(&DefaultProvider, path)
60108}
6110962110pub fn get_memory_path() -> Result<String> {
63111 let root_config = get_or_create_config()?;
64112 let memory_config = root_config
6565- .get("memory")
113113+ .get("data")
66114 .ok_or_else(|| anyhow!("memory section doesnt exist"))?
67115 .as_table()
6868- .expect("Failed to parse to table (memory)");
116116+ .expect("Failed to parse to table (data)");
6911770118 let path = memory_config
71119 .get("path")
7272- .ok_or_else(|| anyhow!("path doesnt exist (memory)"))?
120120+ .ok_or_else(|| anyhow!("path doesnt exist (data)"))?
73121 .as_str()
74122 .expect("parse failed (memory)");
75123 if path.is_empty() {
76124 Err(anyhow::anyhow!(format!("NOT SET")))
77125 } else {
7878- Ok(path.to_owned())
126126+ Ok(PathBuf::from_str(path)?
127127+ .join("memory")
128128+ .to_str()
129129+ .ok_or_else(|| anyhow!("failed to convert path to str"))?
130130+ .to_owned())
79131 }
80132}
81133···8713988140pub fn create_default_memory_folder() -> Result<PathBuf> {
89141 let memory_path = get_default_memory_path()?;
9090- fs::create_dir_all(&memory_path).context("Failed to create tiles memory directory")?;
142142+ fs::create_dir_all(&memory_path).context("Failed to create tiles user data directory")?;
91143 Ok(memory_path)
92144}
93145···98150 false
99151}
100152101101-fn set_memory_path_with_provider<P: ConfigProvider>(_provider: &P, path: &str) -> Result<String> {
153153+fn set_user_data_path_with_provider<P: ConfigProvider>(
154154+ _provider: &P,
155155+ path: &str,
156156+) -> Result<String> {
102157 let path_buf = PathBuf::from_str(path)?;
103158 if path_buf.try_exists()? {
104159 let mut root_config = get_or_create_config()?;
105160 let mut memory_config = root_config
106106- .get("memory")
107107- .ok_or_else(|| anyhow!("memory section doesnt exist"))?
161161+ .get("data")
162162+ .ok_or_else(|| anyhow!("data section doesnt exist"))?
108163 .as_table()
109109- .expect("Failed to parse to table (memory)")
164164+ .expect("Failed to parse to table (data)")
110165 .clone();
111166 memory_config.insert(String::from("path"), toml::Value::String(path.to_owned()));
112112- root_config.insert(String::from("memory"), toml::Value::Table(memory_config));
167167+ root_config.insert(String::from("data"), toml::Value::Table(memory_config));
113168 save_config(&root_config)?;
114169 } else {
115170 return Err(anyhow::anyhow!(format!(
···127182 let tiles_config_dir = DefaultProvider.get_config_dir()?;
128183 let config_toml_path = tiles_config_dir.join("config.toml");
129184130130- fs::create_dir_all(&tiles_config_dir).context("Failed to create config directory")?;
131185 if config_toml_path.try_exists()? {
132186 let config_str = fs::read_to_string(config_toml_path)?;
133187 Ok(config_str.parse::<Table>()?)
···138192 id = ''
139193 nickname = ''
140194141141- [memory]
195195+ [data]
142196 path = ''
143197 "#,
144198 )?;
···162216#[cfg(test)]
163217mod tests {
164218165165- use super::*;
219219+ // use super::*;
166220167167- #[test]
168168- fn test_create_config_file() -> Result<()> {
169169- let _config_table = get_or_create_config()?;
170170- Ok(())
171171- }
221221+ // #[test]
222222+ // fn test_create_config_file() -> Result<()> {
223223+ // let _config_table = get_or_create_config()?;
224224+ // Ok(())
225225+ // }
172226}