feat: add count method

This commit is contained in:
Dmitriy Pleshevskiy 2020-08-07 02:03:11 +03:00
parent 85ddd8fb4e
commit 9ebbf7d038
11 changed files with 156 additions and 20 deletions

View file

@ -428,6 +428,84 @@ impl SonicChannel {
bucket: &'a str => Some(bucket),
object: &'a str => Some(object),
);
#[doc=r#"
Bucket count in indexed search data of your collection.
Note: This method requires enabling the `ingest` feature and start
connection in Ingest mode.
```rust,no_run
# use sonic_channel::*;
# fn main() -> result::Result<()> {
let ingest_channel = SonicChannel::connect_with_start(
ChannelMode::Ingest,
"localhost:1491",
"SecretPassword",
)?;
let bucket_count = ingest_channel.bucket_count("search")?;
dbg!(bucket_count);
# Ok(())
# }
```
"#]
use CountCommand for fn bucket_count<'a>(
collection: &'a str,
);
#[doc=r#"
Object count of bucket in indexed search data.
Note: This method requires enabling the `ingest` feature and start
connection in Ingest mode.
```rust,no_run
# use sonic_channel::*;
# fn main() -> result::Result<()> {
let ingest_channel = SonicChannel::connect_with_start(
ChannelMode::Ingest,
"localhost:1491",
"SecretPassword",
)?;
let object_count = ingest_channel.object_count("search", "default")?;
dbg!(object_count);
# Ok(())
# }
```
"#]
use CountCommand for fn object_count<'a>(
collection: &'a str,
bucket: &'a str => Some(bucket),
);
#[doc=r#"
Object word count in indexed bucket search data.
Note: This method requires enabling the `ingest` feature and start
connection in Ingest mode.
```rust,no_run
# use sonic_channel::*;
# fn main() -> result::Result<()> {
let ingest_channel = SonicChannel::connect_with_start(
ChannelMode::Ingest,
"localhost:1491",
"SecretPassword",
)?;
let word_count = ingest_channel.word_count("search", "default", "recipe:296")?;
dbg!(word_count);
# Ok(())
# }
```
"#]
use CountCommand for fn word_count<'a>(
collection: &'a str,
bucket: &'a str => Some(bucket),
object: &'a str => Some(object),
);
}
#[cfg(feature = "search")]
@ -572,7 +650,7 @@ impl SonicChannel {
"SecretPassword",
)?;
let result = ingest_channel.suggest("search", "default", "Beef", 5)?;
let result = ingest_channel.suggest_with_limit("search", "default", "Beef", 5)?;
dbg!(result);
# Ok(())
# }

40
src/commands/count.rs Normal file
View file

@ -0,0 +1,40 @@
use super::StreamCommand;
use crate::result::*;
#[doc(hidden)]
#[derive(Debug, Default)]
pub struct CountCommand<'a> {
pub collection: &'a str,
pub bucket: Option<&'a str>,
pub object: Option<&'a str>,
}
impl StreamCommand for CountCommand<'_> {
type Response = usize;
fn message(&self) -> String {
let mut message = format!("COUNT {}", self.collection);
if let Some(bucket) = self.bucket {
message.push_str(&format!(" {}", bucket));
if let Some(object) = self.object {
message.push_str(&format!(" {}", object));
}
}
message.push_str("\r\n");
message
}
fn receive(&self, message: String) -> Result<Self::Response> {
if message.starts_with("RESULT ") {
let count = message.split_whitespace().last().unwrap_or_default();
count.parse().map_err(|_| {
Error::new(ErrorKind::QueryResponseError(
"Cannot parse count of count method response to usize",
))
})
} else {
Err(Error::new(ErrorKind::WrongSonicResponse))
}
}
}

View file

@ -33,9 +33,7 @@ impl StreamCommand for FlushCommand<'_> {
))
})
} else {
Err(Error::new(ErrorKind::QueryResponseError(
"Sonic response are wrong. Please write issue to github.",
)))
Err(Error::new(ErrorKind::WrongSonicResponse))
}
}
}

View file

@ -3,6 +3,8 @@ mod start;
mod ping;
#[cfg(feature = "ingest")]
mod count;
#[cfg(feature = "ingest")]
mod flush;
#[cfg(feature = "ingest")]
@ -20,6 +22,8 @@ pub(crate) use start::StartCommand;
pub(crate) use ping::PingCommand;
#[cfg(feature = "ingest")]
pub(crate) use count::CountCommand;
#[cfg(feature = "ingest")]
pub(crate) use flush::FlushCommand;
#[cfg(feature = "ingest")]

View file

@ -13,6 +13,10 @@ impl StreamCommand for PingCommand {
fn receive(&self, message: String) -> Result<Self::Response> {
dbg!(&message);
Ok(message == "PONG\r\n")
if message == "PONG\r\n" {
Ok(true)
} else {
Err(Error::new(ErrorKind::WrongSonicResponse))
}
}
}

View file

@ -1,5 +1,5 @@
use super::StreamCommand;
use crate::result::{Error, ErrorKind, Result};
use crate::result::*;
#[derive(Debug, Default)]
pub struct PopCommand<'a> {
@ -31,7 +31,7 @@ impl StreamCommand for PopCommand<'_> {
)))
} else {
Err(Error::new(ErrorKind::QueryResponseError("Cannot parse result")))
Err(Error::new(ErrorKind::WrongSonicResponse))
}
}
}

View file

@ -1,5 +1,5 @@
use super::StreamCommand;
use crate::result::Result;
use crate::result::*;
#[derive(Debug, Default)]
pub struct PushCommand<'a> {
@ -27,6 +27,11 @@ impl StreamCommand for PushCommand<'_> {
fn receive(&self, message: String) -> Result<Self::Response> {
dbg!(&message);
Ok(message == "OK\r\n")
if message == "OK\r\n" {
Ok(true)
} else {
Err(Error::new(ErrorKind::WrongSonicResponse))
}
}
}

View file

@ -44,9 +44,7 @@ impl StreamCommand for QueryCommand<'_> {
dbg!(&message);
match RE.captures(&message) {
None => Err(Error::new(ErrorKind::QueryResponseError(
"Sonic response are wrong. Please write issue to github.",
))),
None => Err(Error::new(ErrorKind::WrongSonicResponse)),
Some(caps) => {
if &caps["pending_query_id"] != &caps["event_query_id"] {
Err(Error::new(ErrorKind::QueryResponseError(

View file

@ -1,5 +1,5 @@
use super::StreamCommand;
use crate::result::Result;
use crate::result::*;
#[derive(Debug, Default)]
pub struct QuitCommand;
@ -13,6 +13,10 @@ impl StreamCommand for QuitCommand {
fn receive(&self, message: String) -> Result<Self::Response> {
dbg!(&message);
Ok(message.starts_with("ENDED "))
if message.starts_with("ENDED ") {
Ok(true)
} else {
Err(Error::new(ErrorKind::WrongSonicResponse))
}
}
}

View file

@ -40,9 +40,7 @@ impl StreamCommand for SuggestCommand<'_> {
dbg!(&message);
match RE.captures(&message) {
None => Err(Error::new(ErrorKind::QueryResponseError(
"Sonic response are wrong. Please write issue to github.",
))),
None => Err(Error::new(ErrorKind::WrongSonicResponse)),
Some(caps) => {
if &caps["pending_suggest_id"] != &caps["event_suggest_id"] {
Err(Error::new(ErrorKind::QueryResponseError(

View file

@ -4,7 +4,7 @@ use std::fmt;
/// Sugar if you expect only sonic-channel error type in result
pub type Result<T> = std::result::Result<T, Error>;
/// Wrap for sonic channel error kind. This type has std::error::Error
/// Wrap for sonic channel error kind. This type has std::error::Error
/// implementation and you can use boxed trait for catch other errors
/// like this.
#[derive(Debug)]
@ -16,10 +16,10 @@ impl StdError for Error {}
impl Error {
/// Creates new Error with sonic channel error kind
///
///
/// ```rust
/// use sonic_channel::result::*;
///
///
/// let err = Error::new(ErrorKind::ConnectToServer);
/// ```
pub fn new(kind: ErrorKind) -> Self {
@ -47,6 +47,10 @@ pub enum ErrorKind {
/// Error in query response with additional message.
QueryResponseError(&'static str),
/// Response from sonic server are wrong! Actually it may happen if you use
/// unsupported sonic backend version. Please write issue to the github repo.
WrongSonicResponse,
}
impl fmt::Display for Error {
@ -60,6 +64,9 @@ impl fmt::Display for Error {
ErrorKind::QueryResponseError(message) => {
write!(f, "Error in query response: {}", message)
}
ErrorKind::WrongSonicResponse => {
write!(f, "Sonic response are wrong. Please write issue to github.")
}
}
}
}