zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
use crate::prelude2::*;

use std::str::FromStr;

use crate::core::auth0::Requestor;
use crate::core::auth0::UserDetails;
use crate::websocket::webchat::actions::Broadcast;
use crate::websocket::webchat::connection::Connection;
use crate::websocket::webchat::ctx;
use crate::websocket::webchat::output::Level;
use crate::websocket::webchat::output::OutputMessageType;

use crate::websocket::webchat::ctx::WEBCHAT_BROADCAST_CHANNEL;
use crate::websocket::webchat::ctx::WEBCHAT_CLOSE_CONNECTION_CHANNEL;

/// 建立连接
pub async fn ws(
    request: HttpRequest,
    stream: web::Payload,
    context: web::Data<ctx::WebChatContext>,
    requestor: web::ReqData<Requestor>,
) -> core::result::Result<HttpResponse, actix_web::Error> {
    let requestor = requestor.into_inner();
    let srv = context.server.clone();

    actix_web_actors::ws::start(Connection::established(srv, requestor), &request, stream)
}

/// 查询在线用户
pub async fn all_users(
    request: HttpRequest,
    context: web::Data<ctx::WebChatContext>,
    requestor: web::ReqData<Requestor>,
) -> impl Responder {
    use crate::websocket::webchat::handlers::all_users_handler::GetAllUsers;

    let _requestor = requestor.into_inner();
    let _srv = context.server.clone();

    let _all_users = _srv
        .send(GetAllUsers)
        .await
        .map_err(|e| Error::throw("", Some(e)))?;

    let hashmap: HashMap<String, UserDetails> = _all_users.into_iter().collect();

    request.json(200, R::ok(hashmap))
}

/// 踢掉一个连接
pub async fn close(
    request: HttpRequest,
    app_state: web::Data<AppContext>,
    query: web::Query<HashMap<String, String>>,
    _requestor: web::ReqData<Requestor>,
) -> impl Responder {
    // 验证权限,只有管理员能执行该操作
    // TODO
    let _connection_id = query
        .get("connection_id")
        .ok_or_else(|| Error::invalid_request("Missing form data field: connection_id"))?;

    app_state
        .rudis()
        .publishs(&WEBCHAT_CLOSE_CONNECTION_CHANNEL, _connection_id)
        .await
        .map_err(|e| Error::throw("", Some(e)))?;

    request.json(200, R::ok("pending"))
}

/// 广播一条消息
pub async fn broadcast(
    request: HttpRequest,
    app_state: web::Data<AppContext>,
    _context: web::Data<ctx::WebChatContext>,
    query: web::Query<HashMap<String, String>>,
    data: actix_web::web::Bytes,
) -> impl Responder {
    // 验证权限,只有管理员能执行该操作
    // TODO

    let level = query
        .get("level")
        .ok_or_else(|| Error::invalid_request("Missing query string parameter: level"))?;

    let ty = query
        .get("ty")
        .ok_or_else(|| Error::invalid_request("Missing query string parameter: ty"))?;

    let level = Level::from_str(level).map_err(|e| {
        Error::invalid_request(format!("Invalid parameter: level={}: error={}", level, e))
    })?;

    let ty = OutputMessageType::from_str(ty).map_err(|e| {
        Error::invalid_request(format!("Invalid parameter: ty={}: error={}", ty, e))
    })?;

    let _data = crate::commons::bytes_to_string(data.to_vec())?;

    let _broadcast = Broadcast {
        level,
        ty,
        msg: _data,
    };

    app_state
        .rudis()
        .publishs(
            &WEBCHAT_BROADCAST_CHANNEL,
            &serde_json::to_string(&_broadcast).map_err(|e| Error::throw("", Some(e)))?,
        )
        .await
        .map_err(|e| Error::throw("", Some(e)))?;

    request.json(200, R::ok(_broadcast))
}