Skip to content

Instantly share code, notes, and snippets.

@tsoutsman
Last active July 31, 2022 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsoutsman/000f2ffd67dd65549298a2bc2a949624 to your computer and use it in GitHub Desktop.
Save tsoutsman/000f2ffd67dd65549298a2bc2a949624 to your computer and use it in GitHub Desktop.
// The tracking issue (#36887) has been open since 2016; I don't think it's
// getting removed any time soon.
#![allow(invalid_type_param_default)]
#![feature(associated_type_defaults)]
#![no_std]
extern crate alloc;
use alloc::{string::String, sync::Arc, vec::Vec};
use memory::MappedPages;
use path::Path;
use spin::Mutex;
pub type NodeRef<Fs, Kind> = Arc<Mutex<dyn Node<FileSystem = Fs, Kind = Kind>>>;
pub trait Node {
type FileSystem: FileSystem;
type Kind: NodeKind;
fn name(&self) -> String;
fn parent(&self) -> Option<NodeRef<Self::FileSystem, Directory>>;
fn absolute_path(&self) -> Path;
fn as_specific(&self) -> SpecificNodeKind<Self::FileSystem>;
}
pub trait FileNode: Node {
fn as_mapping(&self) -> Result<&MappedPages, &'static str>;
}
pub trait DirectoryNode: Node {
fn get<Kind = Any>(&self, path: &Path) -> Option<NodeRef<Self::FileSystem, Kind>>
where
Kind: NodeKind;
fn insert<Kind>(
&mut self,
node: NodeRef<Self::FileSystem, Kind>,
) -> Result<Option<NodeRef<Self::FileSystem, Kind>>, &'static str>
where
Kind: NodeKind;
fn remove<Kind>(
&mut self,
node: NodeRef<Self::FileSystem, Kind>,
) -> Option<NodeRef<Self::FileSystem, Kind>>
where
Kind: NodeKind;
fn list(&self) -> Vec<NodeRef<Self::FileSystem, Any>>;
}
pub struct Any;
impl private::Sealed for Any {}
impl FileSystem for Any {
type Allowed = dyn FileSystem<Allowed = dyn FileSystem<Allowed = WhatHere>>;
}
impl NodeKind for Any {
fn from_any<Fs>(node: NodeRef<Fs, Any>) -> Option<NodeRef<Fs, Self>>
where
Fs: FileSystem,
{
Some(node)
}
}
pub struct Directory;
impl private::Sealed for Directory {}
impl NodeKind for Directory {
fn from_any<Fs>(node: NodeRef<Fs, Any>) -> Option<NodeRef<Fs, Self>>
where
Fs: FileSystem,
{
match node.lock().as_specific() {
SpecificNodeKind::Directory(d) => Some(d),
_ => None,
}
}
}
pub struct File;
impl private::Sealed for File {}
impl NodeKind for File {
fn from_any<Fs>(node: NodeRef<Fs, Any>) -> Option<NodeRef<Fs, Self>>
where
Fs: FileSystem,
{
match node.lock().as_specific() {
SpecificNodeKind::File(f) => Some(f),
_ => None,
}
}
}
pub trait DirectoryGetKind: private::Sealed {}
pub trait NodeKind: private::Sealed {
fn from_any<Fs>(node: NodeRef<Fs, Any>) -> Option<NodeRef<Fs, Self>>
where
Fs: FileSystem;
}
pub enum SpecificNodeKind<Fs> {
File(NodeRef<Fs, File>),
Directory(NodeRef<Fs, Directory>),
}
pub trait FileSystem {
type Allowed: FileSystem = Self;
}
mod private {
pub trait Sealed {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment