# nectar
crates.io badge docs.rs badge
`nectar` is a Tokio codec providing a partial Telnet protocol (RFC 854) implementation. Supports primary negotiation options: DO, DONT, WILL, WONT. Supports subnegotiation (NAWS, custom byte sequences). Aims to implement some of the popular MUD protocol extensions. ## Usage Simply use ```cargo add nectar``` in your root project directory. You must also be using `tokio-utils` with the `codec` feature enabled, as well as `tokio`. See the Tokio **[docs](https://docs.rs/tokio-util/latest/tokio_util/codec/struct.Framed.html)** if you wish to dive deeper into codecs. Essentially it is just a way to encode and decode the underlying TCP Stream in a structured manner - in this case, our structure being the Telnet protocol. ## Example See the **[echo_server](/examples/echo_server)** directory for a working example with commented code. If you have cloned the `nectar` repository, you can run the echo server with cargo and then connect with `telnet localhost 5000`. *Note: Make sure you check the dependencies in the example `Cargo.toml` file.* ```rust #[tokio::main] async fn main() -> Result<(), Box> { let addr = SocketAddr::from(([127, 0, 0, 1], 5000)); let listener = TcpListener::bind(addr).await?; println!("telnet server started on: {}", addr); // Standard Tokio setup - we accept new connections and pass the // stream off to our handler function where the real work happens. loop { while let Ok((stream, _)) = listener.accept().await { tokio::spawn(async move { if let Err(e) = handler(stream).await { eprintln!("error: {}", e); } }); } } } async fn handler(stream: TcpStream) -> Result<(), Box> { // We construct a 'Frame', which is just a wrapper around the underlying // stream that is decoded by the `nectar::TelnetCodec`. let mut frame = Framed::new(stream, TelnetCodec::new(1024)); // In a real application, you would want to handle Some(Err(_)) and None // variants, but for this example we'll be succinct for simplicities sake. while let Some(Ok(msg)) = frame.next().await { match msg { // We'll keep it simple and only match against the Message event. TelnetEvent::Message(string) => { // Let's echo back what we received. frame.send(TelnetEvent::Message(string)).await?; } _ => break, } } } ``` You can check out the **[Blossom](https://github.com/robertwayne/blossom)** source code for an example of `nectar` in a more complex, real-world scenario. ## License nectar source code is dual-licensed under either - **[MIT License](/LICENSE-MIT)** - **[Apache License, Version 2.0](/LICENSE-APACHE)** at your option.