RefCell<Option<T>> can model a cache that starts empty and is filled when the value is first requested.

Program

Play the program to choose a source value and store it in a small cache.

refcell_cache.rs
use std::cell::RefCell;

fn main() {
    let source = ;
    let cache = RefCell::new(None);
    let value = cached_value(&cache, source);
    println!("{value}");
}

fn cached_value(cache: &RefCell<Option<String>>, source: &str) -> String {
    if cache.borrow().is_none() {
        *cache.borrow_mut() = Some(source.to_string());
    }
    cache.borrow().clone().unwrap()
}
use std::cell::RefCell;

fn main() {
    let source = ;
    let cache = RefCell::new(None);
    let value = cached_value(&cache, source);
    println!("{value}");
}

fn cached_value(cache: &RefCell<Option<String>>, source: &str) -> String {
    if cache.borrow().is_none() {
        *cache.borrow_mut() = Some(source.to_string());
    }
    cache.borrow().clone().unwrap()
}
use std::cell::RefCell;

fn main() {
    let source = ;
    let cache = RefCell::new(None);
    let value = cached_value(&cache, source);
    println!("{value}");
}

fn cached_value(cache: &RefCell<Option<String>>, source: &str) -> String {
    if cache.borrow().is_none() {
        *cache.borrow_mut() = Some(source.to_string());
    }
    cache.borrow().clone().unwrap()
}
Option cache `None` means the cache is empty; `Some(value)` stores the computed data.
borrow_mut `borrow_mut` opens a checked mutable borrow for filling the cache.
clone The helper returns an owned `String` so the borrow does not escape the function.