Skip to content

Commit eedc105

Browse files
committed
WIP: rough subscription manager API proposal
1 parent 35138cd commit eedc105

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ mod profile;
3333
pub mod relay_pool_manager;
3434
mod result;
3535
mod route;
36+
pub mod submgr;
3637
mod subscriptions;
3738
mod support;
3839
mod test_data;

src/submgr.rs

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#![allow(unused)]
2+
3+
use std::collections::HashMap;
4+
use std::error::Error;
5+
use std::fmt;
6+
7+
use enostr::Filter;
8+
use nostrdb;
9+
10+
/// The Subscription Manager
11+
///
12+
/// NOTE - This interface wishes it was called Subscriptions but there
13+
/// already is one. Using a lame (but short) placeholder name instead
14+
/// for now ...
15+
///
16+
/// ```ignore
17+
/// use std::error::Error;
18+
///
19+
/// use notedeck::submgr::{SubMgr, SubSpecBuilder, SubError};
20+
/// use enostr::Filter;
21+
///
22+
/// #[tokio::main]
23+
/// async fn main() -> Result<(), Box<dyn Error>> {
24+
/// let mut submgr = SubMgr::new();
25+
///
26+
/// let filter = Filter::new().kinds(vec![1, 2, 3]).build();
27+
/// let ep = submgr.subscribe(SubSpecBuilder::new(vec![filter]).build())?;
28+
/// loop {
29+
/// match ep.next().await {
30+
/// Ok(nks) => {
31+
/// // process the note keys
32+
/// },
33+
/// Err(SubError::ReevaluateState) => {
34+
/// // not really an error, break out of loop and reevaluate state
35+
/// break;
36+
/// },
37+
/// Err(err) => {
38+
/// // something bad happened
39+
/// eprintln!("Error: {:?}", err);
40+
/// break;
41+
/// },
42+
/// }
43+
/// }
44+
/// submgr.unsubscribe(ep)?;
45+
/// Ok(())
46+
/// }
47+
/// ```
48+
49+
#[derive(Debug)]
50+
pub enum SubError {
51+
ReevaluateState,
52+
InternalError(String),
53+
NdbError(nostrdb::Error),
54+
}
55+
56+
impl From<nostrdb::Error> for SubError {
57+
fn from(err: nostrdb::Error) -> Self {
58+
SubError::NdbError(err)
59+
}
60+
}
61+
62+
impl fmt::Display for SubError {
63+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64+
match self {
65+
SubError::ReevaluateState => write!(f, "ReevaluateState"),
66+
SubError::InternalError(msg) => write!(f, "Internal error: {}", msg),
67+
SubError::NdbError(err) => write!(f, "nostrdb error: {}", err),
68+
}
69+
}
70+
}
71+
72+
impl Error for SubError {}
73+
74+
pub type SubResult<T> = Result<T, SubError>;
75+
76+
pub struct SubId(nostrdb::Subscription);
77+
78+
#[derive(Debug)]
79+
pub enum SubConstraint {
80+
OneShot, // terminate subscription after initial query
81+
Local, // only query the local db, no remote subs
82+
OutboxRelays(Vec<String>), // ensure one of these is in the active relay set
83+
AllowedRelays(Vec<String>), // if not empty, only use these relays
84+
BlockedRelays(Vec<String>), // if not empty, don't use these relays
85+
// other constraints as we think of them ...
86+
}
87+
88+
pub struct SubSpecBuilder {
89+
rmtid: Option<String>,
90+
filters: Vec<Filter>,
91+
is_oneshot: bool,
92+
is_local: bool,
93+
outbox_relays: Vec<String>,
94+
allowed_relays: Vec<String>,
95+
blocked_relays: Vec<String>,
96+
}
97+
98+
impl SubSpecBuilder {
99+
pub fn new(filters: Vec<Filter>) -> Self {
100+
unimplemented!();
101+
}
102+
pub fn rmtid(mut self, id: String) -> Self {
103+
unimplemented!();
104+
}
105+
// ... more here ...
106+
pub fn build(self) -> SubSpec {
107+
unimplemented!();
108+
}
109+
}
110+
111+
pub struct SubSpec {
112+
rmtid: String,
113+
filters: Vec<Filter>,
114+
constraints: Vec<SubConstraint>,
115+
allowed_relays: Vec<String>,
116+
blocked_relays: Vec<String>,
117+
is_oneshot: bool,
118+
}
119+
120+
pub struct SubMgr {
121+
subs: HashMap<SubId, (SubSpec, SubEndpoint)>,
122+
}
123+
124+
impl SubMgr {
125+
pub fn new() -> Self {
126+
SubMgr {
127+
subs: HashMap::new(),
128+
}
129+
}
130+
131+
pub fn subscribe(&mut self, sub: SubSpec) -> SubResult<SubEndpoint> {
132+
unimplemented!();
133+
}
134+
135+
pub fn unsubscribe(&mut self, ep: SubEndpoint) -> SubResult<()> {
136+
unimplemented!();
137+
}
138+
}
139+
140+
pub struct SubEndpoint {
141+
id: SubId,
142+
// internals omitted ...
143+
}
144+
145+
impl SubEndpoint {
146+
pub async fn next(&self) -> SubResult<Vec<nostrdb::NoteKey>> {
147+
unimplemented!();
148+
}
149+
}

0 commit comments

Comments
 (0)