ferrin_core/generate_text/
result.rs1use ferrin_message::Message;
4use ferrin_spec::FinishReason;
5use ferrin_spec::ProviderMetadata;
6use ferrin_spec::Usage;
7use ferrin_spec::Warning;
8
9use super::StepResult;
10
11#[derive(Debug, Clone, PartialEq)]
13pub struct GenerateTextResult<O> {
14 pub steps: Vec<StepResult>,
16 pub total_usage: Usage,
18 pub output: O,
20}
21
22impl<O> GenerateTextResult<O> {
23 #[must_use]
29 pub fn last_step(&self) -> &StepResult {
30 #[allow(clippy::expect_used, reason = "the loop records at least one step")]
31 self.steps.last().expect("at least one step")
32 }
33
34 #[must_use]
36 pub fn text(&self) -> String {
37 self.last_step().text()
38 }
39
40 #[must_use]
42 pub fn reasoning_text(&self) -> Option<String> {
43 self.last_step().reasoning_text()
44 }
45
46 #[must_use]
48 pub fn finish_reason(&self) -> &FinishReason {
49 &self.last_step().finish_reason
50 }
51
52 #[must_use]
54 pub fn usage(&self) -> &Usage {
55 &self.last_step().usage
56 }
57
58 #[must_use]
60 pub fn provider_metadata(&self) -> Option<&ProviderMetadata> {
61 self.last_step().provider_metadata.as_ref()
62 }
63
64 #[must_use]
66 pub fn warnings(&self) -> &[Warning] {
67 &self.last_step().warnings
68 }
69
70 #[must_use]
72 pub fn response_messages(&self) -> Vec<Message> {
73 self.steps
74 .iter()
75 .flat_map(|step| step.response.messages.iter().cloned())
76 .collect()
77 }
78
79 pub fn map_output<P>(self, f: impl FnOnce(O) -> P) -> GenerateTextResult<P> {
81 GenerateTextResult {
82 steps: self.steps,
83 total_usage: self.total_usage,
84 output: f(self.output),
85 }
86 }
87}