You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: try_append_value_async.rs
    path of file: ./repos/moka/examples
    
    the code of the file until where you have to start completion: //! This example demonstrates how to append a `char` to a cached `Vec<String>` value.
//! It uses the `and_upsert_with` method of `Cache`.

use std::{io::Cursor, pin::Pin, sync::Arc};

use moka::{
    future::Cache,
    ops::compute::{CompResult, Op},
};
use tokio::{
    io::{AsyncRead, AsyncReadExt},
    sync::RwLock,
};

/// The type of the cache key.
type Key = i32;

/// The type of the cache value.
///
/// We want to store a raw value `String` for each `i32` key. We are going to append
/// a `char` to the `String` value in the cache.
///
/// Note that we have to wrap the `String` in an `Arc<RwLock<_>>`. We need the `Arc`,
/// an atomic reference counted shared pointer, because `and_try_compute_with` method
/// of `Cache` passes a _clone_ of the value to our closure, instead of passing a
/
    
async fn main() -> Result<(), tokio::io::Error> {
    let cache: Cache<Key, Value> = Cache::new(100);

    let key = 0;

    // We are going read a byte at a time from a byte string (`[u8; 3]`).
    let reader = Cursor::new(b"abc");
    tokio::pin!(reader);

    // Read the first char 'a' from the reader, and insert a string "a" to the cache.
    let result = append_to_cached_string(&cache, key, &mut reader).await?;
    let CompResult::Inserted(entry) = result else {
        panic!("`Inserted` should be returned: {result:?}");
    };
    assert_eq!(*entry.into_value().read().await, "a");

    // Read next char 'b' from the reader, and append it the cached string.
    let result = append_to_cached_string(&cache, key, &mut reader).await?;
    let CompResult::ReplacedWith(entry) = result else {
        panic!("`ReplacedWith` should be returned: {result:?}");
    };
    assert_eq!(*entry.into_value().read().await, "ab");

    // Read next char 'c' from the reader, and append it the cached string.
    let result = append_to_cached_string(&cache, key, &mut reader).await?;
    let CompResult::ReplacedWith(entry) = result else {
        panic!("`ReplacedWith` should be returned: {result:?}");
    };
    assert_eq!(*entry.into_value().read().await, "abc");

    // Reading should fail as no more char left.
    let err = append_to_cached_string(&cache, key, &mut reader).await;
    assert_eq!(
        err.expect_err("An error should be returned").kind(),
        tokio::io::ErrorKind::UnexpectedEof
    );

    Ok(())
}