Change variable type in runtime

I have no experience with generics yet, not sure even could help in following situation.

Trying to update Gio/Glib connection type from SocketConnection to TlsClientConnection (that is just wrapper) when certificate exist for some request, as both impl IsA<IOStream> and could work without separated conditions. But I can't change connection datatype in runtime, is any options?

Here is code example:

// Create connection
client.clone().connect_to_uri_async(
    url.clone().as_str(),
    1965,
    Some(&cancellable.clone()),
    move |connect| match connect {
        Ok(connection) => { // < here `connection` has `SocketConnection` type
            // Wrap connection with TLS (if exist)
            let connection = if let Some(certificate) = auth {
                let tls_connection = TlsClientConnection::new(
                    &connection.clone(),
                    None::<&SocketConnectable>,
                )
                .unwrap();
                // Apply authorization
                tls_connection.set_certificate(
                    &certificate,
                );
                tls_connection // < `TlsClientConnection` wrapper
            } // here `connection` could be changed to TlsClientConnection
            else { connection } // < original `SocketConnection`

            // Send request to `SocketConnection` or `TlsClientConnection`
            connection.output_stream().write_bytes_async( // < here both types supported as `impl IsA<IOStream>` 
            
                // ..

In short, I would make something like this:

let connection = if let Some(certificate) = auth {

but connection type could not be changed in runtime, should I use RefCell maybe, or something else here?

Just answered to myself, when writing the question :slight_smile:

it's RefCell with impl IsA<IOStream> type in return.

UPD. wrote this function, RefCell not wanted here (not sure it's perfect but it works)

fn auth(
    connection: impl IsA<IOStream>,
    certificate: Option<TlsCertificate>,
) -> impl IsA<IOStream> {
    if let Some(certificate) = certificate {
        let tls_connection =
            TlsClientConnection::new(&connection, None::<&SocketConnectable>).unwrap(); 
        tls_connection.set_certificate(&certificate);
        tls_connection.upcast::<IOStream>()
    } else {
        connection.upcast::<IOStream>()
    }
}