Я использую генераторы в качестве долгоживущих асинхронных потоков (см. Как реализовать облегченный долгоживущий поток на основе генератора или асинхронной функции в Rust? ) в сценарии взаимодействия с пользователем.Мне нужно передать пользовательский ввод в генератор на каждом шаге.Я думаю, что могу сделать это с RefCell
, но не ясно, как передать ссылку на RefCell
внутри генератора при создании его экземпляра?
fn user_scenario() -> impl Generator<Yield = String, Return = String> {
|| {
yield format!("what is your name?");
yield format!("{}, how are you feeling?", "anon");
return format!("{}, bye !", "anon");
}
}
Структура UserData
содержитпользовательский ввод, вторая структура содержит пользовательский сеанс, состоящий из UserData
и экземпляр генератора.Сессии собраны в HashMap
.
struct UserData {
sid: String,
msg_in: String,
msg_out: String,
}
struct UserSession {
udata_cell: RefCell<UserData>,
scenario: Pin<Box<dyn Generator<Yield = String, Return = String>>>,
}
type UserSessions = HashMap<String, UserSession>;
let mut sessions: UserSessions = HashMap::new();
UserData
, созданный во время получения пользовательского ввода - в этот момент мне нужно отправить ссылку на UserData
внутри генератора, обернув егов RefCell
, но я не знаю, как это сделать, поскольку у генератора есть 'static
время жизни, а RefCell
живет меньше!
let mut udata: UserData = read_udata(&mut stream);
let mut session: UserSession;
if udata.sid == "" { //new session
let sid = rnd.gen::<u64>().to_string();
udata.sid = sid.clone();
sessions.insert(
sid.clone(),
UserSession {
udata_cell: RefCell::new(udata),
scenario: Box::pin(user_scenario())
}
);
session = sessions.get_mut(&sid).unwrap();
}
Полный код здесь, но генератор здесь не видит пользовательский ввод.