| 55 | } |
| 56 | |
| 57 | pub fn revert( |
| 58 | &self, |
| 59 | input: &RevertInput, |
| 60 | manager: &mut SessionManager, |
| 61 | ) -> Result<Option<Session>> { |
| 62 | let session = match manager.get(&input.session_id) { |
| 63 | Some(s) => s.clone(), |
| 64 | None => return Ok(None), |
| 65 | }; |
| 66 | |
| 67 | let messages = &session.messages; |
| 68 | let mut last_user_id: Option<String> = None; |
| 69 | let mut revert: Option<RevertInfo> = None; |
| 70 | |
| 71 | for msg in messages { |
| 72 | if msg.role == crate::MessageRole::User { |
| 73 | last_user_id = Some(msg.id.clone()); |
| 74 | } |
| 75 | |
| 76 | if revert.is_some() { |
| 77 | continue; |
| 78 | } |
| 79 | |
| 80 | if msg.id == input.message_id { |
| 81 | if input.part_id.is_none() { |
| 82 | revert = Some(RevertInfo { |
| 83 | message_id: last_user_id.clone().unwrap_or_else(|| msg.id.clone()), |
| 84 | part_id: None, |
| 85 | snapshot: None, |
| 86 | diff: None, |
| 87 | }); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | for part in &msg.parts { |
| 92 | if Some(&part.id) == input.part_id.as_ref() { |
| 93 | revert = Some(RevertInfo { |
| 94 | message_id: msg.id.clone(), |
| 95 | part_id: input.part_id.clone(), |
| 96 | snapshot: None, |
| 97 | diff: None, |
| 98 | }); |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | if let Some(mut rev) = revert { |
| 104 | let existing_snapshot = session.revert.as_ref().and_then(|r| r.snapshot.clone()); |
| 105 | |
| 106 | rev.snapshot = Some( |
| 107 | existing_snapshot |
| 108 | .unwrap_or_else(|| Snapshot::track(&self.worktree).unwrap_or_default()), |
| 109 | ); |
| 110 | |
| 111 | if let Some(ref snapshot) = rev.snapshot { |
| 112 | let diffs = Snapshot::diff(&self.worktree, snapshot)?; |
| 113 | rev.diff = if diffs.is_empty() { |
| 114 | None |