Open ghost opened 7 years ago
Please provide complete example, https://github.com/oldaniel/zap contains just lib, seems to train Service not implemented
Instead of
trait Controller {
type Request = Request;
type Response = Response;
type Error = ZapError;
type Future = ZapResult;
fn call(&self, req: Request) -> ZapResult;
}
try implement service
impl Service for Server {
type Request = Request;
type Response = Response;
type Error = ZapError;
type Future = ZapResult;
fn call(&self, req: Request) -> ZapResult {
}
}
@anton-dutov
My current lib.rs
:
#![feature(associated_type_defaults)]
// Load all crates and modules
extern crate bytes;
extern crate futures;
extern crate httparse;
extern crate tokio_io;
extern crate tokio_proto;
mod request;
mod response;
// Use the stuff we need to
use std::io;
use bytes::BytesMut;
use tokio_io::codec::{Encoder, Decoder, Framed};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_proto::pipeline::ServerProto;
use futures::future;
// Make Server, Handler, Request and Response public accessable
pub use tokio_proto::TcpServer as Server;
pub use request::Request;
pub use response::Response;
/// The expected response result
pub type ZapResult = future::Ok<Response, io::Error>;
pub use std::io::Error as ZapError;
pub trait Controller {
/// Requests handled by the service.
type Request = Request;
/// Responses given by the service.
type Response = Response;
/// Errors produced by the service.
type Error = ZapError;
/// The future response value.
type Future = ZapResult;
/// Process the request and return the response asynchronously.
fn call(&self, req: Request) -> ZapResult;
}
/// A module to import the required things.
pub mod prelude {
pub use ZapResult;
pub use Server;
pub use request::Request;
pub use response::Response;
pub use Http;
pub use Controller;
pub use ZapError;
}
/// Handling incoming requests with tokio-proto
pub struct Http;
impl<T: AsyncRead + AsyncWrite + 'static> ServerProto<T> for Http {
// Setup ServerProto types
type Request = Request;
type Response = Response;
type Transport = Framed<T, HttpCodec>;
type BindTransport = io::Result<Framed<T, HttpCodec>>;
fn bind_transport(&self, io: T) -> io::Result<Framed<T, HttpCodec>> {
// Frame the request with tokio-io and handle it with HttpCodec
Ok(io.framed(HttpCodec))
}
}
/// Encode and decode our request
pub struct HttpCodec;
impl Decoder for HttpCodec {
type Item = Request;
type Error = io::Error;
fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<Request>> {
// Decode our buffer
request::decode(buf)
}
}
impl Encoder for HttpCodec {
type Item = Response;
type Error = io::Error;
fn encode(&mut self, msg: Response, buf: &mut BytesMut) -> io::Result<()> {
// Encode and write response
response::encode(&msg, buf);
Ok(())
}
}
And my current hello-world.rs
:
extern crate zap;
use zap::prelude::*;
struct HelloWorld;
impl Controller for HelloWorld {
fn call(&self, _: zap::Request) -> ZapResult {
let mut resp = Response::new();
resp.body("Hello World!");
resp.ok()
}
}
fn main() {
let addr = "0.0.0.0:8080".parse().unwrap();
let mut server = Server::new(Http, addr);
server.threads(8);
server.serve(move || Ok(HelloWorld));
}
Try that
extern crate zap;
extern crate futures;
extern crate tokio_service;
use futures::{Future, BoxFuture};
use tokio_service::Service;
use std::io::Error as ZapError;
use zap::prelude::{Server, Http};
use zap::prelude::Request as ZapRequest;
use zap::prelude::Response as ZapResponse;
struct HelloWorld;
impl Service for HelloWorld {
type Request = ZapRequest;
type Response = ZapResponse;
type Error = ZapError;
type Future = BoxFuture<Self::Response, Self::Error>;
fn call(&self, _: Self::Request) -> Self::Future {
let mut resp = Self::Response::new();
resp.body("Hello World!");
futures::finished(resp).boxed()
}
}
fn main() {
let addr = "0.0.0.0:8080".parse().unwrap();
let mut server = Server::new(Http, addr);
server.threads(8);
server.serve(move || Ok(HelloWorld));
}
Cargo.toml
[dependencies]
zap = { git = "https://github.com/oldaniel/zap" }
futures = "0.1"
tokio-service = "0.1"
@anton-dutov That's what I had in the early Version. I want to have my own custom trait of tokio_service::Service
so the user saves lines of the type
stuff, becuaae they are the same anyway.
Look at https://github.com/tokio-rs/tokio-proto/blob/master/src/tcp_server.rs#L84 You should implement Service trait anyway or create custom wrapper around service creation with advanced abstraction layer
So while creating a new trait that is base on the
tokio_service::Service
on, I run into some problems. My current code (in short form) looks like:The error I ran into was:
So how can I create a custom trait based on
tokio_service::Service
?