bitflags, fs is very broken

This commit is contained in:
2025-04-16 15:51:15 -04:00
parent bb5d24884f
commit b79234a1f5
7 changed files with 96 additions and 83 deletions

View File

@ -1,6 +1,6 @@
import { cyan, green } from "../shell/color" import { cyan, green } from "../shell/color"
import { get_working_dir_name } from "../rfwfs/library"
import librfwfs, { username } from "../rfwfs/library"
import create from "./create" import create from "./create"
interface Ps1Prompt { interface Ps1Prompt {
@ -43,14 +43,20 @@ function ps1_element(user: HTMLSpanElement, dir: HTMLSpanElement) {
return display return display
} }
function working_dir() { function working_dir_name() {
const dir_name = get_working_dir_name() const dir = librfwfs.home.dir()
return dir_name === "user" ? "~" : dir_name if (dir) {
const dir_name = dir.name.read()
if (dir_name) {
return dir_name === username ? "~" : dir_name
}
}
return "?"
} }
function working_dir_element() { function working_dir_element() {
const user = cyan("user") const user = cyan("user")
const dir = green(" "+working_dir()) const dir = green(" "+working_dir_name())
return ps1_element(user, dir) return ps1_element(user, dir)
} }

View File

@ -1,43 +1,12 @@
import { Permissions } from "./rfwfs/enum" import { Permissions } from "./rfwfs/main"
import rfwfs from "./rfwfs/main" import rfwfs from "./rfwfs/main"
const time_now = (Date.now()/1000)|0 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([ const fs = new rfwfs([
rfwfs.directory("bin", Permissions.r, fs, time_now)
]) ])
rfwfs.directory("bin", Permissions.r, fs, time_now)
export default fs export default fs

View File

@ -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,
}

View File

@ -1,5 +1,5 @@
import { ReadStatus } from "./enum"
import { wrap_entry, type WrapResultEntry } from "./wrap" import { wrap_entry, type WrapResultEntry } from "./wrap"
import { ReadStatus } from "./enum/status"
import rfwfs, { type DirectoryAny, type EntryCollection, type DirectoryAnyDepth } from "./main" import rfwfs, { type DirectoryAny, type EntryCollection, type DirectoryAnyDepth } from "./main"
import fs from "../fs" import fs from "../fs"

View File

@ -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 { wrap_entry, wrap_none, type WrapResultEntry, type WrapResultNone, type WrapBinary, wrap_binary } from "./wrap"
import directory_search from "./index" import directory_search from "./index"
@ -15,22 +16,6 @@ const enum Permissions {
none = 1<<3, 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 FileInner = string | number
type BinaryError = string type BinaryError = string
@ -45,22 +30,31 @@ interface Root<T extends Entry> {
readonly type: EntryType, readonly type: EntryType,
inner: T[], inner: T[],
} }
interface RootFile<T extends Entry> extends Root<T> {
}
interface EntryStripped { interface EntryStripped {
readonly type: EntryType, readonly type: EntryType,
permissions: Permissions, permissions: Permissions,
timestamp: EntryValue<number>, timestamp: EntryValue<number>,
name: EntryValue<string>, name: EntryValue<string>,
} }
interface Entry extends EntryStripped { interface Entry extends EntryStripped {
parent: DirectoryAny, parent: DirectoryAny,
} }
interface EntryFile extends Entry { interface EntryFile extends Entry {
inner: EntryValue<FileInner>, inner: EntryValue<FileInner>,
hash: string, hash: string,
} }
interface EntryCollection<T extends Entry> extends Entry { interface EntryCollection<T extends Entry> extends Entry {
inner: RfwfsDirectory<T>, inner: RfwfsDirectory<T>,
} }
interface EntryBinary extends Entry { interface EntryBinary extends Entry {
inner: RfwfsBinary inner: RfwfsBinary
} }
@ -74,19 +68,6 @@ function strip_entry<T extends 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<T> { class EntryValue<T> {
public inner: T; public inner: T;
protected entry: Entry protected entry: Entry
@ -97,15 +78,24 @@ class EntryValue<T> {
} }
public write<I extends T>(item: I): boolean { public write<I extends T>(item: I): boolean {
if (write_access(this.entry.permissions)) { if (rfwfs.write_access(this.entry.permissions)) {
this.inner = item this.inner = item
return true return true
} }
return false 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 { 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<T extends Entry> {
} }
public clone(file_name: string): WrapResultEntry<T, ReadStatus> { public clone(file_name: string): WrapResultEntry<T, ReadStatus> {
if (read_write_access(this.entry.permissions)) { if (rfwfs.read_write_access(this.entry.permissions)) {
const clone_find = directory_search(this.directory, file_name) const clone_find = directory_search(this.directory, file_name)
if (clone_find) { if (clone_find) {
return wrap_entry(ReadStatus.Ok, { ...clone_find.result }) return wrap_entry(ReadStatus.Ok, { ...clone_find.result })
@ -134,7 +124,7 @@ class RfwfsDirectory<T extends Entry> {
} }
public find(file_name: string): WrapResultEntry<T, ReadStatus> { public find(file_name: string): WrapResultEntry<T, ReadStatus> {
if (read_write_access(this.entry.permissions)) { if (rfwfs.read_write_access(this.entry.permissions)) {
const file_search = directory_search(this.directory, file_name) const file_search = directory_search(this.directory, file_name)
if (file_search) { if (file_search) {
return wrap_entry(ReadStatus.Ok, file_search.result) return wrap_entry(ReadStatus.Ok, file_search.result)
@ -145,7 +135,7 @@ class RfwfsDirectory<T extends Entry> {
} }
public push<E extends T>(entry: E): WrapResultNone<PushStatus> { public push<E extends T>(entry: E): WrapResultNone<PushStatus> {
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) const no_duplicates = directory_search(this.directory, entry.name.inner)
if (!no_duplicates) { if (!no_duplicates) {
this.directory.push(entry) this.directory.push(entry)
@ -158,7 +148,7 @@ class RfwfsDirectory<T extends Entry> {
} }
public pop(file_name: string): WrapResultEntry<T, ReadStatus> { public pop(file_name: string): WrapResultEntry<T, ReadStatus> {
if (read_write_access(this.entry.permissions)) { if (rfwfs.read_write_access(this.entry.permissions)) {
const pop_find = directory_search(this.directory, file_name) const pop_find = directory_search(this.directory, file_name)
if (pop_find) { if (pop_find) {
this.directory.splice(pop_find.status, 1) this.directory.splice(pop_find.status, 1)
@ -180,7 +170,7 @@ class RfwfsBinary {
} }
public execute(): WrapBinary { public execute(): WrapBinary {
if (execute_access(this.entry.permissions)) { if (rfwfs.execute_access(this.entry.permissions)) {
try { try {
this.lambda(() => strip_entry(this.entry)) this.lambda(() => strip_entry(this.entry))
} catch(binary_e) { } catch(binary_e) {
@ -205,16 +195,45 @@ class rfwfs_static {
public static is_root<T extends Entry>(entry: Root<T>): boolean { public static is_root<T extends Entry>(entry: Root<T>): boolean {
return entry.type === EntryType.Root 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<T extends Entry> extends rfwfs_static { class rfwfs<T extends Entry> extends rfwfs_static {
protected root: Root<T>; public root: Root<T>;
constructor(inner: T[]) { constructor(inner: T[]) {
super() super()
this.root = { type: EntryType.Root, inner: inner } 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( public static file(
default_name: string, default_name: string,
default_permissions: Permissions, default_permissions: Permissions,
@ -224,8 +243,8 @@ class rfwfs<T extends Entry> extends rfwfs_static {
): EntryFile { ): EntryFile {
const file = { type: EntryType.File } as EntryFile const file = { type: EntryType.File } as EntryFile
file.hash = "0" file.hash = "0"
file.parent = default_parent
file.permissions = default_permissions 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.inner = new EntryValue(file, default_inner ? default_inner : "")
file.name = new EntryValue(file, default_name) file.name = new EntryValue(file, default_name)
@ -276,9 +295,6 @@ export {
type FileInner, type FileInner,
type EntryFile, type EntryFile,
type Entry, type Entry,
ExecuteStatus,
Permissions, Permissions,
PushStatus,
ReadStatus,
EntryType, EntryType,
} }

View File

@ -1,5 +1,5 @@
import { type BinaryError, type Entry } from "./main" import { type BinaryError, type Entry } from "./main"
import { ExecuteStatus } from "./main" import { ExecuteStatus } from "./enum/status"
const enum Option { const enum Option {
Ok, Ok,

View File

@ -1,10 +1,11 @@
import { set_working_dir, SetDirStatus } from "../../../rfwfs/library" import { ReadStatus } from "../../../rfwfs/enum"
import type { Args, Term } from "../list" import type { Args, Term } from "../list"
import lib from "../../../rfwfs/library"
import stdout from "../../../elements/stdout" import stdout from "../../../elements/stdout"
export default function cd(term: Term, args: Args): boolean { 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) { if (new_dir_status === SetDirStatus.NotADirectory) {
term.appendChild(stdout(`cd: "${args[1]}" is not a directory`)) term.appendChild(stdout(`cd: "${args[1]}" is not a directory`))