Start API refactor to remove separate Tree
We want trees to just be notes. We want to reference notes by Path instead of object ids. Stop thinking about the fs implementation and the fuse service with the same terms - they will be different backends.
This commit is contained in:
parent
abbef64bbc
commit
41480a39c9
5 changed files with 245 additions and 234 deletions
|
|
@ -1,14 +1,39 @@
|
|||
from typing import Protocol, runtime_checkable, Optional, Dict, List, Self, NamedTuple, Iterable, TypedDict
|
||||
from typing import Protocol, runtime_checkable, Optional, Dict, List, Self, NamedTuple, Iterable, TypedDict, Iterator
|
||||
from uuid import UUID
|
||||
from pathlib import PurePosixPath
|
||||
import datetime as dt
|
||||
|
||||
import errno
|
||||
|
||||
type ObjectId = int | str | UUID
|
||||
|
||||
class TroveError(Exception):
|
||||
"""Base class for all Trove errors."""
|
||||
|
||||
class ErrorWithErrno(TroveError):
|
||||
"""Raised when an error occurs with an errno."""
|
||||
|
||||
def __init__(self, error: int, *args):
|
||||
super().__init__(*args)
|
||||
self.errno = error
|
||||
|
||||
class ErrorExists(ErrorWithErrno):
|
||||
"""Raised when a note already exists."""
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(errno.EEXIST, *args)
|
||||
|
||||
class ErrorNotFound(ErrorWithErrno):
|
||||
"""Raised when a note is not found."""
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(errno.ENOENT, *args)
|
||||
|
||||
class ErrorNotEmpty(ErrorWithErrno):
|
||||
"""Raised when a directory is not empty."""
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(errno.ENOTEMPTY, *args)
|
||||
|
||||
|
||||
class BadNoteType(TypeError):
|
||||
"""Raised when an invalid note type is encountered."""
|
||||
|
||||
|
|
@ -21,6 +46,12 @@ class NoteNotFound(KeyError):
|
|||
class OpenArguments(TypedDict):
|
||||
create: bool
|
||||
|
||||
class TreeEntry(NamedTuple):
|
||||
name: str
|
||||
object_id: ObjectId
|
||||
|
||||
DEFAULT_MIME = "application/octet-stream"
|
||||
|
||||
@runtime_checkable
|
||||
class Note(Protocol):
|
||||
"""
|
||||
|
|
@ -64,10 +95,30 @@ class Note(Protocol):
|
|||
"""Write the raw content of the note."""
|
||||
...
|
||||
|
||||
def children(self) -> Iterator[TreeEntry]:
|
||||
"""Get all children of this note."""
|
||||
...
|
||||
|
||||
def child(self, name: str) -> 'Note':
|
||||
"""Retrieve a child note by name."""
|
||||
...
|
||||
|
||||
def new_child(self, name: str, mime: str, content: bytes | None, executable: bool, hidden: bool) -> 'Note':
|
||||
"""Create a new child note."""
|
||||
...
|
||||
|
||||
def rm_child(self, name: str, recurse: bool):
|
||||
"""Remove a child note."""
|
||||
...
|
||||
|
||||
def has_children(self) -> bool:
|
||||
"""Check if note has children."""
|
||||
return next(self.children(), None) is not None
|
||||
|
||||
|
||||
def new_child(note: Note, name: str, mime: str = DEFAULT_MIME, content: bytes | None = None, executable: bool = False, hidden: bool = False) -> Note:
|
||||
return note.new_child(name=name, mime=mime, content=content, executable=executable, hidden=hidden)
|
||||
|
||||
class TreeEntry(NamedTuple):
|
||||
name: str
|
||||
object_id: ObjectId
|
||||
|
||||
@runtime_checkable
|
||||
class Tree(Protocol):
|
||||
|
|
@ -87,17 +138,10 @@ class Tree(Protocol):
|
|||
"""Remove a directory from the tree."""
|
||||
...
|
||||
|
||||
def child(self, name: str) -> Note:
|
||||
"""Retrieve a child note by name."""
|
||||
...
|
||||
|
||||
def entries(self) -> Iterable[TreeEntry]:
|
||||
"""Return all entries in the directory"""
|
||||
...
|
||||
|
||||
def list(self) -> dict[str, int]:
|
||||
"""Return all entries as {name: object_id}."""
|
||||
...
|
||||
|
||||
@runtime_checkable
|
||||
class TreeNote(Note, Tree, Protocol):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue