Repository: diesel-rs/diesel
File: diesel/src/pg/connection/mod.rs (Rust)

Code before:
        self.conn.pqnotifies()
    }
}

extern "C" fn noop_notice_processor(_: *mut libc::c_void, _message: *const libc::c_char) {}

mod private {
    use super::*;

    #[allow(missing_debug_implementations)]
    pub struct ConnectionAndTransactionManager {
        pub(super) raw_connection: RawConnection,
        pub(super) transaction_state: AnsiTransactionManager,
        pub(super) instrumentation: DynInstrumentation,
    }

    pub trait PgLoadingMode<B> {
        const USE_ROW_BY_ROW_MODE: bool;
        type Cursor<'conn, 'query>: Iterator<Item = QueryResult<Self::Row<'conn, 'query>>>;
        type Row<'conn, 'query>: crate::row::Row<'conn, Pg>;

        fn get_cursor<'conn, 'query>(
            raw_connection: &'conn mut ConnectionAndTransactionManager,
            result: PgResult,
            source: impl QueryFragment<Pg> + 'query,
        ) -> QueryResult<Self::Cursor<'conn, 'query>>;
    }

    impl PgLoadingMode<DefaultLoadingMode> for PgConnection {
        const USE_ROW_BY_ROW_MODE: bool = false;
        type Cursor<'conn, 'query> = Cursor;
        type Row<'conn, 'query> = self::row::PgRow;

        fn get_cursor<'conn, 'query>(
            conn: &'conn mut ConnectionAndTransactionManager,
            result: PgResult,
            source: impl QueryFragment<Pg> + 'query,
        ) -> QueryResult<Self::Cursor<'conn, 'query>> {
            update_transaction_manager_status(
                Cursor::new(result, &mut conn.raw_connection),
                conn,
                &crate::debug_query(&source),
                true,
            )
        }
    }

    impl PgLoadingMode<PgRowByRowLoadingMode> for PgConnection {
        const USE_ROW_BY_ROW_MODE: bool = true;
        type Cursor<'conn, 'query> = RowByRowCursor<'conn, 'query>;
        type Row<'conn, 'query> = self::row::PgRow;

Review comment (suggestion):
I would prefer moving all notifications related code into a separate submodule to keep the code clean

Code after:
    /// #     let connection = &mut establish_connection();
    ///
    /// // register the notifications channel we want to receive notifications for
    /// diesel::sql_query("LISTEN example_channel").execute(connection)?;
    /// // send some notification
    /// // this is usually done from a different connection/thread/application
    /// diesel::sql_query("NOTIFY example_channel, 'additional data'").execute(connection)?;
    ///
    /// for result in connection.notifications_iter() {
    ///     let notification = result.unwrap();
    ///     assert_eq!(notification.channel, "example_channel");
    ///     assert_eq!(notification.payload, "additional data");
    ///
    ///     println!(
    ///         "Notification received from server process with id {}.",
    ///         notification.process_id
    ///    );
    /// }
    /// # Ok(())
    /// # }
    /// ```
    pub fn notifications_iter(&mut self) -> impl Iterator<Item = QueryResult<PgNotification>> + '_ {
        let conn = &self.connection_and_transaction_manager.raw_connection;
        std::iter::from_fn(move || conn.pq_notifies().transpose())
    }
}

extern "C" fn noop_notice_processor(_: *mut libc::c_void, _message: *const libc::c_char) {}

mod private {
    use super::*;

    #[allow(missing_debug_implementations)]
    pub struct ConnectionAndTransactionManager {
        pub(super) raw_connection: RawConnection,
        pub(super) transaction_state: AnsiTransactionManager,
        pub(super) instrumentation: DynInstrumentation,
    }

    pub trait PgLoadingMode<B> {
        const USE_ROW_BY_ROW_MODE: bool;
        type Cursor<'conn, 'query>: Iterator<Item = QueryResult<Self::Row<'conn, 'query>>>;
        type Row<'conn, 'query>: crate::row::Row<'conn, Pg>;

        fn get_cursor<'conn, 'query>(
            raw_connection: &'conn mut ConnectionAndTransactionManager,
            result: PgResult,
            source: impl QueryFragment<Pg> + 'query,
        ) -> QueryResult<Self::Cursor<'conn, 'query>>;
    }