From 22b9e1f3d5a7c6ed821da5e2a1dfd8203dadcf38 Mon Sep 17 00:00:00 2001 From: rhpidfyre Date: Thu, 24 Apr 2025 01:23:11 -0400 Subject: [PATCH] wip: root can add directories to itself --- src/rt/fs.ts | 7 +- src/rt/rfwfs/main.ts | 179 ++++++++++++++++++++++++++++--------------- 2 files changed, 121 insertions(+), 65 deletions(-) diff --git a/src/rt/fs.ts b/src/rt/fs.ts index 90b9881..8ca2d4c 100644 --- a/src/rt/fs.ts +++ b/src/rt/fs.ts @@ -2,11 +2,10 @@ import { Permissions } from "./rfwfs/main" import rfwfs from "./rfwfs/main" -const time_now = (Date.now()/1000)|0 +const time_now = (Date.now()/1000) | 0 -const fs = new rfwfs([ - rfwfs.directory("bin", Permissions.r, fs, time_now) -]) +const fs = new rfwfs() +fs.add_file(default_name, default_permissions) export default fs \ No newline at end of file diff --git a/src/rt/rfwfs/main.ts b/src/rt/rfwfs/main.ts index d23b954..ba5ac34 100644 --- a/src/rt/rfwfs/main.ts +++ b/src/rt/rfwfs/main.ts @@ -1,5 +1,5 @@ import { ReadStatus, PushStatus, ExecuteStatus } from "./enum/status" -import { wrap_entry, wrap_none, type WrapResultEntry, type WrapResultNone, type WrapBinary, wrap_binary } from "./wrap" +import { wrap_entry, wrap_none, wrap_binary, type WrapResultEntry, type WrapResultNone, type WrapBinary } from "./wrap" import directory_search from "./index" @@ -15,6 +15,7 @@ const enum Permissions { x = 1<<2, none = 1<<3, } +const enum ROOT_ID { TRUNK = "/" } type FileInner = string | number type BinaryError = string @@ -26,15 +27,6 @@ type Directory = EntryCollection type DirectoryAny = EntryCollection type DirectoryAnyDepth = EntryCollection -interface Root { - readonly type: EntryType, - inner: T[], -} - -interface RootFile extends Root { - -} - interface EntryStripped { readonly type: EntryType, permissions: Permissions, @@ -42,8 +34,8 @@ interface EntryStripped { name: EntryValue, } -interface Entry extends EntryStripped { - parent: DirectoryAny, +interface Entry extends EntryStripped { + parent: T, } interface EntryFile extends Entry { @@ -59,6 +51,15 @@ interface EntryBinary extends Entry { inner: RfwfsBinary } +interface Root { + readonly type: EntryType, + readonly permissions: Permissions, + readonly timestamp: EntryValueRoot, + readonly parent: null, + readonly inner: RfwfsRootDirectory, + readonly name: ROOT_ID.TRUNK, +} + function strip_entry(entry: T): EntryStripped { return { type: entry.type, @@ -68,15 +69,53 @@ function strip_entry(entry: T): EntryStripped { } } +function fs_dir_clone(directory: T[], file_name: string): WrapResultEntry { + const clone_find = directory_search(directory, file_name) + if (clone_find) { + return wrap_entry(ReadStatus.Ok, { ...clone_find.result }) + } + return wrap_entry(ReadStatus.NotFound) +} + +function fs_dir_find(directory: T[], file_name: string): WrapResultEntry { + const file_search = directory_search(directory, file_name) + if (file_search) { + return wrap_entry(ReadStatus.Ok, file_search.result) + } + return wrap_entry(ReadStatus.NotFound) +} + +function fs_dir_push(directory: T[], entry: E) { + const no_duplicates = directory_search(directory, entry.name.inner) + if (!no_duplicates) { + directory.push(entry) + directory.sort() + return wrap_none(PushStatus.Ok) + } + return wrap_none(PushStatus.Duplicate) +} + +function fs_dir_pop(directory: T[], file_name: string): WrapResultEntry { + const pop_find = directory_search(directory, file_name) + if (pop_find) { + directory.splice(pop_find.status, 1) + return wrap_entry(ReadStatus.Ok, pop_find.result) + } + return wrap_entry(ReadStatus.NotFound) +} + class EntryValue { public inner: T; - protected entry: Entry + protected entry: Entry; constructor(entry: Entry, inner_default: T) { this.inner = inner_default this.entry = entry } + /** + Safe write + */ public write(item: I): boolean { if (rfwfs.write_access(this.entry.permissions)) { this.inner = item @@ -99,6 +138,18 @@ class EntryValue { } } +class EntryValueRoot { + protected inner: T; + + constructor(inner: T) { + this.inner = inner + } + + public read(): T { + return this.inner + } +} + class RfwfsDirectory { public directory: T[]; protected entry: Entry; @@ -114,52 +165,61 @@ class RfwfsDirectory { public clone(file_name: string): WrapResultEntry { 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 }) - } - return wrap_entry(ReadStatus.NotFound) + return fs_dir_clone(this.directory, file_name) } return wrap_entry(ReadStatus.Denied) } public find(file_name: string): WrapResultEntry { 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) - } - return wrap_entry(ReadStatus.NotFound) + return fs_dir_find(this.directory, file_name) } return wrap_entry(ReadStatus.Denied) } public push(entry: E): WrapResultNone { 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) - this.directory.sort() - return wrap_none(PushStatus.Ok) - } - return wrap_none(PushStatus.Duplicate) + return fs_dir_push(this.directory, entry) } return wrap_none(PushStatus.Denied) } public pop(file_name: string): WrapResultEntry { 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) - return wrap_entry(ReadStatus.Ok, pop_find.result) - } - return wrap_entry(ReadStatus.NotFound) + fs_dir_pop(this.directory, file_name) } return wrap_entry(ReadStatus.Denied) } } +class RfwfsRootDirectory { + public directory: T[]; + + constructor() { + this.directory = [] + } + + public sort() { + this.directory.sort((a,z) => a.name.inner.localeCompare(z.name.inner)) + } + + public clone(file_name: string): WrapResultEntry { + return fs_dir_clone(this.directory, file_name) + } + + public find(file_name: string): WrapResultEntry { + return fs_dir_find(this.directory, file_name) + } + + public push(entry: E): WrapResultNone { + return fs_dir_push(this.directory, entry) + } + + public pop(file_name: string): WrapResultEntry { + return fs_dir_pop(this.directory, file_name) + } +} + class RfwfsBinary { public lambda: BinaryLambda; protected entry: Entry; @@ -182,7 +242,10 @@ class RfwfsBinary { } } -class rfwfs_static { +class rfwfs_lib { + public static is_root(entry: T): boolean { + return entry.type === EntryType.Root + } public static is_dir(entry: T): boolean { return entry.type === EntryType.Directory } @@ -192,9 +255,6 @@ class rfwfs_static { public static is_binary(entry: T): boolean { return entry.type === EntryType.Binary } - public static is_root(entry: Root): boolean { - return entry.type === EntryType.Root - } public static read_access(permissions: Permissions): boolean { return (permissions & Permissions.r) !== 0 @@ -210,28 +270,24 @@ class rfwfs_static { } } -class rfwfs extends rfwfs_static { +class rfwfs extends rfwfs_lib { public root: Root; - constructor(inner: T[]) { + constructor() { super() - this.root = { type: EntryType.Root, inner: inner } + this.root = { + type: EntryType.Root, + permissions: Permissions.r | Permissions.w, + timestamp: new EntryValueRoot((Date.now()/1000) | 0), + parent: null, + inner: new RfwfsRootDirectory(), + name: ROOT_ID.TRUNK, + } as Root } - 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 push_directory_into_root(dir: EntryCollection): EntryCollection { + this.root.inner.push(dir) + return dir } public static file( @@ -245,7 +301,7 @@ class rfwfs extends rfwfs_static { file.hash = "0" file.permissions = default_permissions file.parent = default_parent - file.timestamp = new EntryValue(file, default_timestamp ? default_timestamp : (Date.now()/1000)|0) + 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 @@ -261,7 +317,7 @@ class rfwfs extends rfwfs_static { const directory = { type: EntryType.Directory } as EntryCollection directory.parent = default_parent directory.permissions = default_permissions - directory.timestamp = new EntryValue(directory, default_timestamp ? default_timestamp : (Date.now()/1000)|0) + directory.timestamp = new EntryValue(directory, default_timestamp ? default_timestamp : (Date.now()/1000) | 0) directory.inner = new RfwfsDirectory(directory, default_inner ? default_inner : []) directory.name = new EntryValue(directory, default_name) return directory @@ -277,7 +333,7 @@ class rfwfs extends rfwfs_static { const binary = { type: EntryType.Binary } as EntryBinary binary.parent = default_parent binary.permissions = default_permissions - binary.timestamp = new EntryValue(binary, default_timestamp ? default_timestamp : (Date.now()/1000)|0) + binary.timestamp = new EntryValue(binary, default_timestamp ? default_timestamp : (Date.now()/1000) | 0) binary.inner = new RfwfsBinary(binary, default_inner ? default_inner : () => {}) binary.name = new EntryValue(binary, default_name) return binary @@ -286,8 +342,8 @@ class rfwfs extends rfwfs_static { export default rfwfs export { - type EntryCollection, type DirectoryAnyDepth, + type EntryCollection, type RfwfsDirectory, type DirectoryAny, type BinaryError, @@ -297,4 +353,5 @@ export { type Entry, Permissions, EntryType, + ROOT_ID, } \ No newline at end of file