-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0b879c1
commit db9ea36
Showing
6 changed files
with
162 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use async_trait::async_trait; | ||
use tokio::net::{TcpStream, UnixStream}; | ||
|
||
use crate::{Error, Rpc}; | ||
use memcrab_protocol::{Msg, ParseError, Request, Response, Socket}; | ||
|
||
pub struct Tcp { | ||
inner: Socket<TcpStream>, | ||
} | ||
|
||
impl Tcp { | ||
pub(crate) fn from_stream(stream: TcpStream) -> Self { | ||
let inner = Socket::new(stream); | ||
Self { inner } | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl Rpc for Tcp { | ||
async fn call(&mut self, request: Request) -> Result<Response, Error> { | ||
self.inner.send(Msg::Request(request)).await?; | ||
match self.inner.recv().await? { | ||
Msg::Response(resp) => Ok(resp), | ||
_ => Err(Error::Parse(ParseError::UnknownMsgKind)), | ||
} | ||
} | ||
} | ||
|
||
pub struct Unix { | ||
inner: Socket<UnixStream>, | ||
} | ||
|
||
impl Unix { | ||
pub(crate) fn from_stream(stream: UnixStream) -> Self { | ||
let inner = Socket::new(stream); | ||
Self { inner } | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl Rpc for Unix { | ||
async fn call(&mut self, request: Request) -> Result<Response, Error> { | ||
self.inner.send(Msg::Request(request)).await?; | ||
match self.inner.recv().await? { | ||
Msg::Response(resp) => Ok(resp), | ||
_ => Err(Error::Parse(ParseError::UnknownMsgKind)), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,34 @@ | ||
/*! | ||
# memcrab | ||
## Usage | ||
```no_run | ||
use memcrab::{RawClient, connections::Tcp, Rpc as _, Error}; | ||
#[tokio::main] | ||
async fn main() -> Result<(), Error> { | ||
let addr = "127.0.0.1:80".parse().unwrap(); | ||
let mut client = RawClient::<Tcp>::connect(addr).await?; | ||
client.set("date", vec![2, 3, 24]).await?; | ||
let name = client.get("name").await?; | ||
match name { | ||
Some(val) => println!("got {:?} from cache", val), | ||
None => println!("cache miss for name"), | ||
} | ||
Ok(()) | ||
} | ||
``` | ||
*/ | ||
|
||
#[allow(unused_variables)] | ||
mod raw_client; | ||
|
||
// pub use raw_client::RawClient; | ||
pub mod connections; | ||
|
||
pub use memcrab_protocol::Error; | ||
pub use raw_client::{RawClient, Rpc}; | ||
|
||
#[cfg(test)] | ||
mod tests {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,70 @@ | ||
// use std::net::SocketAddr; | ||
// | ||
// use memcrab_protocol::ClientSideError; | ||
// | ||
// pub struct RawClient {} | ||
// | ||
// impl RawClient { | ||
// pub async fn connect(addr: SocketAddr) -> Result<Self, ClientSideError> { | ||
// todo!() | ||
// } | ||
// pub async fn get(&self, key: impl Into<String>) -> Result<Option<Vec<u8>>, ClientSideError> { | ||
// let key = key.into(); | ||
// todo!() | ||
// } | ||
// pub async fn set(&self, key: impl Into<String>, value: Vec<u8>) -> Result<(), ClientSideError> { | ||
// let key = key.into(); | ||
// todo!() | ||
// } | ||
// } | ||
use crate::{ | ||
connections::{Tcp, Unix}, | ||
Error, | ||
}; | ||
use memcrab_protocol::{Msg, Request, Response}; | ||
|
||
use std::{net::SocketAddr, path::Path}; | ||
use tokio::net::{TcpStream, UnixStream}; | ||
|
||
#[async_trait::async_trait] | ||
pub trait Rpc | ||
where | ||
Self: Sized, | ||
{ | ||
async fn call(&mut self, request: Request) -> Result<Response, Error>; | ||
} | ||
|
||
pub struct RawClient<C> { | ||
conn: C, | ||
} | ||
|
||
impl<C> RawClient<C> { | ||
fn new(conn: C) -> Self { | ||
Self { conn } | ||
} | ||
} | ||
|
||
fn invalid_resp(resp: Response) -> Error { | ||
Error::InvalidMsg(Msg::Response(resp)) | ||
} | ||
|
||
impl<C> RawClient<C> | ||
where | ||
C: Rpc, | ||
{ | ||
pub async fn get(&mut self, key: impl Into<String>) -> Result<Option<Vec<u8>>, Error> { | ||
let key = key.into(); | ||
match self.conn.call(Request::Get(key)).await? { | ||
Response::Value(val) => Ok(Some(val)), | ||
Response::KeyNotFound => Ok(None), | ||
resp => Err(invalid_resp(resp)), | ||
} | ||
} | ||
pub async fn set(&mut self, key: impl Into<String>, value: Vec<u8>) -> Result<(), Error> { | ||
let key = key.into(); | ||
let request = Request::Set { | ||
key, | ||
value, | ||
expiration: 0, | ||
}; | ||
match self.conn.call(request).await? { | ||
Response::Ok => Ok(()), | ||
resp => Err(invalid_resp(resp)), | ||
} | ||
} | ||
} | ||
|
||
impl RawClient<Tcp> { | ||
pub async fn connect(addr: SocketAddr) -> Result<Self, Error> { | ||
let stream = TcpStream::connect(addr).await?; | ||
Ok(Self::new(Tcp::from_stream(stream))) | ||
} | ||
} | ||
|
||
impl RawClient<Unix> { | ||
pub async fn connect(path: impl AsRef<Path>) -> Result<Self, Error> { | ||
let stream = UnixStream::connect(path).await?; | ||
Ok(Self::new(Unix::from_stream(stream))) | ||
} | ||
} |