aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs/namespace/namespace.py
diff options
context:
space:
mode:
authorMatthias Baumgartner <dev@igsor.net>2022-12-08 16:33:36 +0100
committerMatthias Baumgartner <dev@igsor.net>2022-12-08 16:33:36 +0100
commit729f025f392d45b621941da9d052834e0d81506e (patch)
treed8ff3b58267da4735dbce67fc168ab31e687f58f /bsfs/namespace/namespace.py
parentbbfcee4fffc553b5dd08f37a79dd6ccddbf340f8 (diff)
downloadbsfs-729f025f392d45b621941da9d052834e0d81506e.tar.gz
bsfs-729f025f392d45b621941da9d052834e0d81506e.tar.bz2
bsfs-729f025f392d45b621941da9d052834e0d81506e.zip
namespaces
Diffstat (limited to 'bsfs/namespace/namespace.py')
-rw-r--r--bsfs/namespace/namespace.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/bsfs/namespace/namespace.py b/bsfs/namespace/namespace.py
new file mode 100644
index 0000000..8080f5d
--- /dev/null
+++ b/bsfs/namespace/namespace.py
@@ -0,0 +1,80 @@
+"""
+
+Part of the BlackStar filesystem (bsfs) module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import typing
+
+# bsfs imports
+from bsfs.utils import URI, typename
+
+# exports
+__all__: typing.Sequence[str] = (
+ 'ClosedNamespace',
+ 'Namespace',
+ )
+
+
+## code ##
+
+class Namespace():
+ """A namespace consists of a common prefix that is used in a set of URIs.
+
+ Note that the prefix must include the separator between
+ path and fragment (typically a '#' or a '/').
+ """
+
+ # namespace prefix.
+ prefix: URI
+
+ def __init__(self, prefix: URI):
+ self.prefix = URI(prefix)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, type(self)) and self.prefix == other.prefix
+
+ def __hash__(self) -> int:
+ return hash((type(self), self.prefix))
+
+ def __str__(self) -> str:
+ return f'{typename(self)}({self.prefix})'
+
+ def __repr__(self) -> str:
+ return f'{typename(self)}({self.prefix})'
+
+ def __getattr__(self, fragment: str) -> URI:
+ """Return prefix + fragment."""
+ return URI(self.prefix + fragment)
+
+ def __getitem__(self, fragment: str) -> URI:
+ """Alias for getattr(self, fragment)."""
+ return self.__getattr__(fragment)
+
+
+class ClosedNamespace(Namespace):
+ """Namespace that covers a restricted set of URIs."""
+
+ # set of permissible fragments.
+ fragments: typing.Set[str]
+
+ def __init__(self, prefix: URI, *args: str):
+ super().__init__(prefix)
+ self.fragments = set(args)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return super().__eq__(other) and self.fragments == other.fragments
+
+ def __hash__(self) -> int:
+ return hash((type(self), self.prefix, tuple(sorted(self.fragments))))
+
+ def __getattr__(self, fragment: str) -> URI:
+ """Return prefix + fragment.
+ Raises a KeyError if the fragment is not allowed in this namespace.
+ """
+ if fragment not in self.fragments:
+ raise KeyError('fragment')
+ return super().__getattr__(fragment)
+
+## EOF ##