use std::sync::Arc;
use blockstore::Blockstore;
use crate::client::{ClientBehaviour, ClientConfig};
use crate::multihasher::{Multihasher, MultihasherTable};
use crate::server::ServerBehaviour;
use crate::utils::stream_protocol;
use crate::{Behaviour, Error, Result};
pub struct BehaviourBuilder<const S: usize, B>
where
B: Blockstore + 'static,
{
protocol_prefix: Option<String>,
blockstore: Arc<B>,
client: ClientConfig,
multihasher: MultihasherTable<S>,
}
impl<const S: usize, B> BehaviourBuilder<S, B>
where
B: Blockstore + 'static,
{
pub(crate) fn new(blockstore: Arc<B>) -> Self {
BehaviourBuilder {
protocol_prefix: None,
blockstore,
client: ClientConfig {
set_send_dont_have: true,
},
multihasher: MultihasherTable::<S>::new(),
}
}
pub fn protocol_prefix(mut self, prefix: &str) -> Result<Self> {
if !prefix.starts_with('/') {
return Err(Error::InvalidProtocolPrefix(prefix.to_owned()));
}
self.protocol_prefix = Some(prefix.to_owned());
Ok(self)
}
pub fn client_set_send_dont_have(mut self, enable: bool) -> Self {
self.client.set_send_dont_have = enable;
self
}
pub fn register_multihasher<M>(mut self, multihasher: M) -> Self
where
M: Multihasher<S> + Send + Sync + 'static,
{
self.multihasher.register(multihasher);
self
}
pub fn build(self) -> Behaviour<S, B> {
let blockstore = self.blockstore;
let multihasher = Arc::new(self.multihasher);
let protocol_prefix = self.protocol_prefix.as_deref();
Behaviour {
protocol: stream_protocol(protocol_prefix, "/ipfs/bitswap/1.2.0")
.expect("prefix checked by beetswap::BehaviourBuilder::protocol_prefix"),
client: ClientBehaviour::new(self.client, blockstore.clone(), protocol_prefix),
server: ServerBehaviour::new(blockstore, protocol_prefix),
multihasher,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use blockstore::InMemoryBlockstore;
#[test]
fn invalid_protocol_prefix() {
assert!(matches!(
BehaviourBuilder::<64, _>::new(Arc::new(InMemoryBlockstore::<64>::new()))
.protocol_prefix("foo"),
Err(Error::InvalidProtocolPrefix(_))
));
}
}