Repository: DioxusLabs/dioxus
File: packages/fullstack-core/src/streaming.rs (Rust)

Code before:
        for subscriber in subscribers {
            subscriber.mark_dirty();
        }
    }

    /// Get the current status of the streaming response. This method is reactive and will cause
    /// the current reactive context to rerun when the status changes.
    pub fn streaming_state(&self) -> StreamingStatus {
        *self.current_status.read()
    }

    /// Access the http request parts mutably. This will allow you to modify headers and other parts of the request.
    pub fn parts_mut(&self) -> parking_lot::RwLockWriteGuard<'_, http::request::Parts> {
        self.request_headers.write()
    }

    /// Run a future within the scope of this FullstackContext.
    pub async fn scope<F, R>(self, fut: F) -> R
    where
        F: std::future::Future<Output = R>,
    {
        FULLSTACK_CONTEXT.scope(self, fut).await
    }

    /// Extract an axum extractor from the current request.
    pub async fn extract<T: FromRequestParts<()>>() -> Result<T, ServerFnError> {
        let this = Self::current()
            .ok_or_else(|| ServerFnError::new("No FullstackContext found".to_string()))?;

        let parts = this.request_headers.read().clone();
        let request =
            axum_core::extract::Request::from_parts(parts, axum_core::body::Body::empty());
        match T::from_request(request, &()).await {
            Ok(res) => Ok(res),
            Err(err) => {
                let resp = err.into_response();
                Err(ServerFnError::from_axum_response(resp).await)
            }
        }
    }

    /// Get the current `FullstackContext` if it exists. This will return `None` if called on the client
    /// or outside of a streaming response on the server or server function.
    pub fn current() -> Option<Self> {
        if let Ok(context) = FULLSTACK_CONTEXT.try_get() {
            return Some(context);
        }

        if let Some(rt) = dioxus_core::Runtime::try_current() {
            let id = rt.try_current_scope_id()?;
            if let Some(ctx) = rt.consume_context::<FullstackContext>(id) {

Review comment (suggestion):
This changed from `FromRequest` to `FromRequestParts` which only allows types that don't consume the body (which is empty here)

The only types `FromRequest` is implemented for that  `FromRequestParts` is not are types like `Body` itself which will not behave correctly with an empty body in server functions

Code after:
        #[allow(clippy::mutable_key_type)]
        let subscribers = std::mem::take(&mut lock.current_status_subscribers);
        for subscriber in subscribers {
            subscriber.mark_dirty();
        }
    }

    /// Get the current status of the streaming response. This method is reactive and will cause
    /// the current reactive context to rerun when the status changes.
    pub fn streaming_state(&self) -> StreamingStatus {
        let mut lock = self.lock.write();
        // Register the current reactive context as a subscriber to changes in the streaming status
        if let Some(ctx) = ReactiveContext::current() {
            lock.current_status_subscribers.insert(ctx);
        }
        lock.current_status
    }

    /// Access the http request parts mutably. This will allow you to modify headers and other parts of the request.
    pub fn parts_mut(&self) -> parking_lot::RwLockWriteGuard<'_, http::request::Parts> {
        self.request_headers.write()
    }

    /// Run a future within the scope of this FullstackContext.
    pub async fn scope<F, R>(self, fut: F) -> R
    where
        F: std::future::Future<Output = R>,
    {
        FULLSTACK_CONTEXT.scope(self, fut).await
    }

    /// Extract an axum extractor from the current request.
    ///
    /// The body of the request is always empty when using this method, as the body can only be consumed once in the server
    /// function extractors.
    pub async fn extract<T: FromRequest<(), M>, M>() -> Result<T, ServerFnError> {
        let this = Self::current()
            .ok_or_else(|| ServerFnError::new("No FullstackContext found".to_string()))?;

        let parts = this.request_headers.read().clone();
        let request = axum_core::extract::Request::from_parts(parts, Default::default());
        match T::from_request(request, &()).await {
            Ok(res) => Ok(res),
            Err(err) => {
                let resp = err.into_response();
                Err(ServerFnError::from_axum_response(resp).await)
            }
        }
    }

    /// Get the current `FullstackContext` if it exists. This will return `None` if called on the client