use bon::Builder;
use serde::{Deserialize, Serialize};
use crate::{
LmcppServer, client::types::generation_settings::TokenIds, error::LmcppResult,
server::ipc::ServerClientExt,
};
impl LmcppServer {
pub fn detokenize<A: DetokenizeRequestProvider>(
&self,
request: A,
) -> LmcppResult<DetokenizeResponse> {
request.with_request(|req| self.client.post("/detokenize", req).map_err(Into::into))
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Builder)]
#[builder(derive(Debug, Clone))]
pub struct DetokenizeRequest {
#[builder(into)]
pub tokens: TokenIds,
}
pub trait DetokenizeRequestProvider {
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R;
}
impl<'a> DetokenizeRequestProvider for &'a DetokenizeRequest {
#[inline]
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R,
{
f(self)
}
}
impl<'a> DetokenizeRequestProvider for &'a mut DetokenizeRequest {
#[inline]
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R,
{
f(self)
}
}
impl DetokenizeRequestProvider for DetokenizeRequest {
#[inline]
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R,
{
f(&self)
}
}
impl<S> DetokenizeRequestProvider for DetokenizeRequestBuilder<S>
where
S: detokenize_request_builder::IsComplete,
{
#[inline]
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R,
{
let req = self.build(); f(&req)
}
}
impl<'a, S> DetokenizeRequestProvider for &'a DetokenizeRequestBuilder<S>
where
S: detokenize_request_builder::IsComplete,
{
#[inline]
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R,
{
let req = self.clone().build();
f(&req)
}
}
impl<'a, S> DetokenizeRequestProvider for &'a mut DetokenizeRequestBuilder<S>
where
S: detokenize_request_builder::IsComplete,
{
#[inline]
fn with_request<F, R>(self, f: F) -> R
where
F: FnOnce(&DetokenizeRequest) -> R,
{
let req = self.clone().build();
f(&req)
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DetokenizeResponse {
pub content: String,
}
#[cfg(test)]
mod tests {
use serial_test::serial;
use super::*;
use crate::{LmcppServer, error::LmcppResult, server::builder::LmcppServerLauncher};
#[test]
#[ignore]
#[serial]
fn test_lmcpp_server_detokenize() -> LmcppResult<()> {
let client = LmcppServerLauncher::default().load()?;
let detok = client.detokenize(DetokenizeRequest::builder().tokens(vec![0u64, 1, 2, 3]))?;
println!("Detokenize response: {:?}", detok);
Ok(())
}
#[test]
#[ignore]
#[allow(unused_mut)]
fn test_lmcpp_server_detokenize_variants() -> LmcppResult<()> {
let client = LmcppServer::dummy();
let req_owned = DetokenizeRequest::builder()
.tokens(vec![0u64, 1, 2])
.build();
let _ = client.detokenize(req_owned);
let mut req_owned = DetokenizeRequest::builder()
.tokens(vec![0u64, 1, 2])
.build();
let _ = client.detokenize(req_owned);
let req_owned = DetokenizeRequest::builder()
.tokens(vec![0u64, 1, 2])
.build();
let _ = client.detokenize(&req_owned);
let mut req_owned = DetokenizeRequest::builder()
.tokens(vec![0u64, 1, 2])
.build();
let _ = client.detokenize(&mut req_owned);
let req_owned = DetokenizeRequest::builder().tokens(vec![0u64, 1, 2]);
let _ = client.detokenize(req_owned);
let mut req_owned = DetokenizeRequest::builder().tokens(vec![0u64, 1, 2]);
let _ = client.detokenize(req_owned);
let req_owned = DetokenizeRequest::builder().tokens(vec![0u64, 1, 2]);
let _ = client.detokenize(&req_owned);
let mut req_owned = DetokenizeRequest::builder().tokens(vec![0u64, 1, 2]);
let _ = client.detokenize(&mut req_owned);
Ok(())
}
}