summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-06-15 19:25:44 +0200
committerMatthias Beyer <mail@beyermatthias.de>2019-06-15 19:25:44 +0200
commit6d4b52c24a768bcc620dbc06f500a9d5bb71eea7 (patch)
tree697ae2904bdcdf0327fb77f0ca66dca0960cd836
parentfcd4d64287ef176b0f2167e29f8b32b188e21e9d (diff)
Move repository types and functionality
-rw-r--r--src/repository/iter/block.rs52
-rw-r--r--src/repository/iter/mod.rs1
-rw-r--r--src/repository/mod.rs3
-rw-r--r--src/repository/profile.rs69
4 files changed, 125 insertions, 0 deletions
diff --git a/src/repository/iter/block.rs b/src/repository/iter/block.rs
new file mode 100644
index 0000000..fb7e609
--- /dev/null
+++ b/src/repository/iter/block.rs
@@ -0,0 +1,52 @@
+use queues::Queue;
+use failure::Error;
+use futures::Future;
+
+use crate::repository::Repository;
+use crate::types::block::Block;
+
+/// An iterator that iterates over `Block`s using a `Repository`
+///
+pub struct BlockIterator {
+ repo: Repository,
+ queue: Queue<impl Future<Block, Error>>,
+}
+
+impl BlockIterator {
+ pub fn new(repo: Repository, initial: IPFSHash) -> Self {
+ Repository {
+ queue: {
+ let q = Queue::default();
+ q.add(repo.get_block(initial));
+ q
+ },
+ repo
+ }
+ }
+}
+
+impl Iterator for BlockIterator {
+ type Item = Result<Block, Error>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Ok(next_block) = self.queue.remove() {
+ match next_block.wait() {
+ Some(block) => {
+ block.parents().iter().for_each(|parent| {
+ self.queue.add({
+ self.repo.get_block(parent)
+ });
+ })
+
+ Some(block)
+ },
+
+ Err(e) => return Some(Err(e)),
+ }
+
+
+ } else {
+ None
+ }
+ }
+}
diff --git a/src/repository/iter/mod.rs b/src/repository/iter/mod.rs
new file mode 100644
index 0000000..a863eaa
--- /dev/null
+++ b/src/repository/iter/mod.rs
@@ -0,0 +1 @@
+pub mod block;
diff --git a/src/repository/mod.rs b/src/repository/mod.rs
index d2e5dd3..aee6a01 100644
--- a/src/repository/mod.rs
+++ b/src/repository/mod.rs
@@ -1,5 +1,8 @@
mod client;
mod repository;
+mod profile;
+mod iter;
pub use repository::Repository;
+pub use profile::ProfileName;
diff --git a/src/repository/profile.rs b/src/repository/profile.rs
new file mode 100644
index 0000000..991a0bf
--- /dev/null
+++ b/src/repository/profile.rs
@@ -0,0 +1,69 @@
+#[derive(Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
+pub struct ProfileName(String);
+
+impl From<String> for ProfileName {
+ fn from(s: String) -> Self {
+ ProfileName(s)
+ }
+}
+
+/// A profile
+///
+/// A profile can be _any_ profile, not only the profile of the user
+#[derive(Debug)]
+pub struct Profile {
+ repository: Repository,
+}
+
+impl Profile {
+
+ /// Create a new Profile.
+ ///
+ /// One does not want this most of the time, see `load`. Use this only for creating a
+ /// completely new profile
+ pub fn new(repository: Repository) -> Result<Self, Error> {
+ unimplemented!()
+ }
+
+ /// Load a profile from the repository
+ pub fn load(repository: Repository, key: Key) -> Result<Self, Error> {
+ unimplemented!()
+ }
+
+ pub fn blocks(&self) -> impl Iterator<Item = Result<Block, Error>> {
+ use crate::repository::iter::block::BlockIterator;
+ BlockIterator::new(&self.repository)
+ }
+}
+
+
+/// The profile of the user of the application
+///
+/// Internally this wraps the `Profile` type, but it provides more functionality, for example
+/// posting new content.
+///
+#[derive(Debug)]
+pub struct UserProfile {
+ profile: Profile
+}
+
+impl UserProfile {
+
+ /// Create a new Profile.
+ ///
+ /// One does not want this most of the time, see `load`. Use this only for creating a
+ /// completely new profile
+ pub fn new(repository: Repository) -> Result<Self, Error> {
+ Ok(UserProfile {
+ profile: Profile::new(repository)?,
+ })
+ }
+
+ /// Load a profile from the repository
+ pub fn load(repository: Repository, key: Key) -> Result<Self, Error> {
+ Ok(UserProfile {
+ profile: Profile::load(repository, key)?,
+ })
+ }
+
+}