Building a text editor in ICED

⚓ Rust    📅 2025-06-02    👤 surdeus    👁️ 2      

surdeus

Warning

This post was published 70 days ago. The information described in this article may have changed.

I am trying to build a collaborative text editor in rust. This editor communicates to other editor via websockets. I have not done the collaboration part yet but I am struggling to first establish the communication via the websockets first

use iced::futures::channel::mpsc;
use iced::futures::{SinkExt, Stream, StreamExt};
use iced::widget::text_editor;
use iced::widget::text_editor::{Action, Content};
use iced::{stream, Element, Subscription, Task};
use std::str::FromStr;
use tokio::net::TcpListener;

#[derive(Debug,Default)]
pub struct Editor{
    content : Content,
    sender : Option<mpsc::Sender<String>>
}

#[derive(Clone,Debug)]
pub enum Message{
    Edit(Action),
    Event(Event),
    None
}

#[derive(Debug,Clone)]
pub enum Event{
    Sender(mpsc::Sender<String>),
    WorkDone
}
impl Editor{
    pub fn new() -> Self{

        Editor {
            content: Content::new(),
            sender: None
        }
    }
    
    pub fn view(&self) -> Element<'_,Message>{
       text_editor(&self.content)
           .placeholder("Here goes test")
           .on_action(Message::Edit)
           .into()
    }
    
    pub fn subscription(&self) -> Subscription<Message>{
        Subscription::run(send_something).map(Message::Event)
    }
    
    pub fn update(&mut self, msg : Message){
        match msg{
           Message::Edit(a) => {
               self.content.perform(a);
          if let Some(mut x) = self.sender.clone(){
               let _ = Task::perform(
                   async move {
                       x.send(String::from_str("some x").unwrap()).await.unwrap();
                   }
               ,|_|Message::None); 
           };
           }, 
            Message::Event(e) => {
                match e{
                   Event::Sender(s) => {
                       self.sender = Some(s);
                   },
                    Event::WorkDone => {}
                }
            }
            _ => ()
        }
    }
    
}


pub fn send_something() -> impl Stream<Item=Event> {
    stream::channel(100,|mut output| async move{
        let tcp_listener = TcpListener::bind("127.0.0.1:9001").await.unwrap();
        if let Ok((stream,addr)) = tcp_listener.accept().await{
           tokio::spawn(async move{
                let ws_stream = tokio_tungstenite::accept_async(stream).await.unwrap();  
               let (sender, mut receiver) = mpsc::channel(100);
               let _ = &mut output.send(Event::Sender(sender)).await.unwrap();
               let (mut out, mut inc) = ws_stream.split();
               while let Some(Ok(x)) = inc.next().await {
                 let txt = x.into_text().unwrap();
                   println!("{:?}",txt);
                   while let Some(msg) = receiver.next().await{
                      out.send(tungstenite::Message::text(msg)).await.unwrap(); 
                   }
               }
               
           });
        }
    })
}


This is the code currently my goal is to open a websocket server and broadcast what I am typing in my ICED editor in the server. I am trying to use ICED subscription to do this but this is not working as expected. Any help would be appreciated.

2 posts - 2 participants

Read full topic

🏷️ rust_feed