diff --git a/src/rt/elements/prompt.ts b/src/rt/elements/prompt.ts index 05a03e7..01ef0b3 100644 --- a/src/rt/elements/prompt.ts +++ b/src/rt/elements/prompt.ts @@ -1,6 +1,6 @@ import { cyan, green } from "../shell/color" -import { get_working_dir_name } from "../rfwfs/library" +import librfwfs, { username } from "../rfwfs/library" import create from "./create" interface Ps1Prompt { @@ -43,14 +43,20 @@ function ps1_element(user: HTMLSpanElement, dir: HTMLSpanElement) { return display } -function working_dir() { - const dir_name = get_working_dir_name() - return dir_name === "user" ? "~" : dir_name +function working_dir_name() { + const dir = librfwfs.home.dir() + if (dir) { + const dir_name = dir.name.read() + if (dir_name) { + return dir_name === username ? "~" : dir_name + } + } + return "?" } function working_dir_element() { const user = cyan("user") - const dir = green(" "+working_dir()) + const dir = green(" "+working_dir_name()) return ps1_element(user, dir) } diff --git a/src/rt/fs.ts b/src/rt/fs.ts index 60a102b..90b9881 100644 --- a/src/rt/fs.ts +++ b/src/rt/fs.ts @@ -1,43 +1,12 @@ -import { Permissions } from "./rfwfs/enum" +import { Permissions } from "./rfwfs/main" import rfwfs from "./rfwfs/main" const time_now = (Date.now()/1000)|0 -// ------------ Home ------------ -const config = rfwfs.directory(".config", Permissions.rw, time_now) -const local = rfwfs.directory(".local", Permissions.rw, time_now) - -const downloads = rfwfs.directory("Downloads", Permissions.rw, time_now) -const pictures = rfwfs.directory("Pictures", Permissions.rw, time_now) -const desktop = rfwfs.directory("Desktop", Permissions.rw, time_now) -const videos = rfwfs.directory("Videos", Permissions.rw, time_now) -const music = rfwfs.directory("Music", Permissions.rw, time_now) - -const user = rfwfs.directory("user", Permissions.r, time_now, [ - config, - local, - downloads, - pictures, - videos, - music, - desktop, -]) - -// /home/ -const home = rfwfs.directory("home", Permissions.r, time_now, [user]) -// ------------ - -// ------------ root ------------ -const bin = rfwfs.directory("bin", Permissions.r, time_now) -const vard = rfwfs.directory("var", Permissions.r, time_now) -const etc = rfwfs.directory("etc", Permissions.r, time_now) -// ------------ - const fs = new rfwfs([ - + rfwfs.directory("bin", Permissions.r, fs, time_now) ]) -rfwfs.directory("bin", Permissions.r, fs, time_now) export default fs \ No newline at end of file diff --git a/src/rt/rfwfs/enum/status.ts b/src/rt/rfwfs/enum/status.ts new file mode 100644 index 0000000..8abbb63 --- /dev/null +++ b/src/rt/rfwfs/enum/status.ts @@ -0,0 +1,21 @@ +const enum PushStatus { + Ok, + Duplicate, + Denied, +} +const enum ReadStatus { + Ok, + NotFound, + Denied, +} +const enum ExecuteStatus { + Ok, + Panic, + Denied, +} + +export { + ExecuteStatus, + ReadStatus, + PushStatus, +} \ No newline at end of file diff --git a/src/rt/rfwfs/library.ts b/src/rt/rfwfs/library.ts index b7c6434..65920b7 100644 --- a/src/rt/rfwfs/library.ts +++ b/src/rt/rfwfs/library.ts @@ -1,5 +1,5 @@ -import { ReadStatus } from "./enum" import { wrap_entry, type WrapResultEntry } from "./wrap" +import { ReadStatus } from "./enum/status" import rfwfs, { type DirectoryAny, type EntryCollection, type DirectoryAnyDepth } from "./main" import fs from "../fs" diff --git a/src/rt/rfwfs/main.ts b/src/rt/rfwfs/main.ts index 8f17d6c..d23b954 100644 --- a/src/rt/rfwfs/main.ts +++ b/src/rt/rfwfs/main.ts @@ -1,3 +1,4 @@ +import { ReadStatus, PushStatus, ExecuteStatus } from "./enum/status" import { wrap_entry, wrap_none, type WrapResultEntry, type WrapResultNone, type WrapBinary, wrap_binary } from "./wrap" import directory_search from "./index" @@ -15,22 +16,6 @@ const enum Permissions { none = 1<<3, } -const enum PushStatus { - Ok, - Duplicate, - Denied, -} -const enum ReadStatus { - Ok, - NotFound, - Denied, -} -const enum ExecuteStatus { - Ok, - Panic, - Denied, -} - type FileInner = string | number type BinaryError = string @@ -45,22 +30,31 @@ interface Root { readonly type: EntryType, inner: T[], } + +interface RootFile extends Root { + +} + interface EntryStripped { readonly type: EntryType, permissions: Permissions, timestamp: EntryValue, name: EntryValue, } + interface Entry extends EntryStripped { parent: DirectoryAny, } + interface EntryFile extends Entry { inner: EntryValue, hash: string, } + interface EntryCollection extends Entry { inner: RfwfsDirectory, } + interface EntryBinary extends Entry { inner: RfwfsBinary } @@ -74,19 +68,6 @@ function strip_entry(entry: T): EntryStripped { } } -function read_write_access(permissions: Permissions): boolean { - return (permissions & (Permissions.r | Permissions.w)) === (Permissions.r | Permissions.w) -} -function execute_access(permissions: Permissions): boolean { - return (permissions & Permissions.x) !== 0 -} -function read_access(permissions: Permissions): boolean { - return (permissions & Permissions.r) !== 0 -} -function write_access(permissions: Permissions): boolean { - return (permissions & Permissions.w) !== 0 -} - class EntryValue { public inner: T; protected entry: Entry @@ -97,15 +78,24 @@ class EntryValue { } public write(item: I): boolean { - if (write_access(this.entry.permissions)) { + if (rfwfs.write_access(this.entry.permissions)) { this.inner = item return true } return false } + /** + Convert the inner file value + + Same as `write` but mutates the inner value `T` into a `FileInner` + */ + public write_into(item: FileInner): boolean { + return this.write(item as T) + } + public read(): T | undefined { - return read_access(this.entry.permissions) ? this.inner : undefined + return rfwfs.write_access(this.entry.permissions) ? this.inner : undefined } } @@ -123,7 +113,7 @@ class RfwfsDirectory { } public clone(file_name: string): WrapResultEntry { - if (read_write_access(this.entry.permissions)) { + if (rfwfs.read_write_access(this.entry.permissions)) { const clone_find = directory_search(this.directory, file_name) if (clone_find) { return wrap_entry(ReadStatus.Ok, { ...clone_find.result }) @@ -134,7 +124,7 @@ class RfwfsDirectory { } public find(file_name: string): WrapResultEntry { - if (read_write_access(this.entry.permissions)) { + if (rfwfs.read_write_access(this.entry.permissions)) { const file_search = directory_search(this.directory, file_name) if (file_search) { return wrap_entry(ReadStatus.Ok, file_search.result) @@ -145,7 +135,7 @@ class RfwfsDirectory { } public push(entry: E): WrapResultNone { - if (read_write_access(this.entry.permissions)) { + if (rfwfs.read_write_access(this.entry.permissions)) { const no_duplicates = directory_search(this.directory, entry.name.inner) if (!no_duplicates) { this.directory.push(entry) @@ -158,7 +148,7 @@ class RfwfsDirectory { } public pop(file_name: string): WrapResultEntry { - if (read_write_access(this.entry.permissions)) { + if (rfwfs.read_write_access(this.entry.permissions)) { const pop_find = directory_search(this.directory, file_name) if (pop_find) { this.directory.splice(pop_find.status, 1) @@ -180,7 +170,7 @@ class RfwfsBinary { } public execute(): WrapBinary { - if (execute_access(this.entry.permissions)) { + if (rfwfs.execute_access(this.entry.permissions)) { try { this.lambda(() => strip_entry(this.entry)) } catch(binary_e) { @@ -205,16 +195,45 @@ class rfwfs_static { public static is_root(entry: Root): boolean { return entry.type === EntryType.Root } + + public static read_access(permissions: Permissions): boolean { + return (permissions & Permissions.r) !== 0 + } + public static write_access(permissions: Permissions): boolean { + return (permissions & Permissions.w) !== 0 + } + public static execute_access(permissions: Permissions): boolean { + return (permissions & Permissions.x) !== 0 + } + public static read_write_access(permissions: Permissions): boolean { + return rfwfs.read_access(permissions) && rfwfs.write_access(permissions) + } } class rfwfs extends rfwfs_static { - protected root: Root; + public root: Root; constructor(inner: T[]) { super() this.root = { type: EntryType.Root, inner: inner } } + public add_file( + default_name: string, + default_permissions: Permissions, + default_timestamp?: number, + default_inner?: FileInner + ): EntryFile { + const file = { type: EntryType.File } as EntryFile + file.hash = "0" + file.permissions = default_permissions + file.parent = this.root + file.timestamp = new EntryValue(file, default_timestamp ? default_timestamp : (Date.now()/1000)|0) + file.inner = new EntryValue(file, default_inner ? default_inner : "") + file.name = new EntryValue(file, default_name) + return file + } + public static file( default_name: string, default_permissions: Permissions, @@ -224,8 +243,8 @@ class rfwfs extends rfwfs_static { ): EntryFile { const file = { type: EntryType.File } as EntryFile file.hash = "0" - file.parent = default_parent file.permissions = default_permissions + file.parent = default_parent file.timestamp = new EntryValue(file, default_timestamp ? default_timestamp : (Date.now()/1000)|0) file.inner = new EntryValue(file, default_inner ? default_inner : "") file.name = new EntryValue(file, default_name) @@ -276,9 +295,6 @@ export { type FileInner, type EntryFile, type Entry, - ExecuteStatus, Permissions, - PushStatus, - ReadStatus, EntryType, } \ No newline at end of file diff --git a/src/rt/rfwfs/wrap.ts b/src/rt/rfwfs/wrap.ts index 337a8ce..7c3b76d 100644 --- a/src/rt/rfwfs/wrap.ts +++ b/src/rt/rfwfs/wrap.ts @@ -1,5 +1,5 @@ import { type BinaryError, type Entry } from "./main" -import { ExecuteStatus } from "./main" +import { ExecuteStatus } from "./enum/status" const enum Option { Ok, diff --git a/src/rt/shell/command/builtin/cd.ts b/src/rt/shell/command/builtin/cd.ts index 19e489b..be6107f 100644 --- a/src/rt/shell/command/builtin/cd.ts +++ b/src/rt/shell/command/builtin/cd.ts @@ -1,10 +1,11 @@ -import { set_working_dir, SetDirStatus } from "../../../rfwfs/library" +import { ReadStatus } from "../../../rfwfs/enum" import type { Args, Term } from "../list" +import lib from "../../../rfwfs/library" import stdout from "../../../elements/stdout" export default function cd(term: Term, args: Args): boolean { - const new_dir_status = set_working_dir(args[1]) + const new_dir_status = lib.traverse_to(args) if (new_dir_status === SetDirStatus.NotADirectory) { term.appendChild(stdout(`cd: "${args[1]}" is not a directory`))