monoloop_loop/transaction/
fake_support.rs1use monoloop_contracts::{
4 Bytes, CanonicalMessage, DialectDescriptor, EncodedExchange, EncodingError,
5 ExchangeInputPolicy, InitialEncodeRequest, OutboundDialectEncoder,
6 ToolContinuationEncodeRequest,
7};
8
9#[derive(Debug, Default)]
11pub struct PanicEncoder;
12
13impl OutboundDialectEncoder for PanicEncoder {
14 fn encode_initial(
15 &self,
16 _request: InitialEncodeRequest<'_>,
17 ) -> Result<EncodedExchange, EncodingError> {
18 panic!("PanicEncoder::encode_initial (§22.2)");
19 }
20
21 fn encode_tool_continuation(
22 &self,
23 _request: ToolContinuationEncodeRequest<'_>,
24 ) -> Result<EncodedExchange, EncodingError> {
25 panic!("PanicEncoder::encode_tool_continuation (§22.2)");
26 }
27}
28
29#[derive(Debug, Default)]
31pub struct RejectEncoder;
32
33impl OutboundDialectEncoder for RejectEncoder {
34 fn encode_initial(
35 &self,
36 _request: InitialEncodeRequest<'_>,
37 ) -> Result<EncodedExchange, EncodingError> {
38 Err(EncodingError::Unsupported("reject encoder"))
39 }
40
41 fn encode_tool_continuation(
42 &self,
43 _request: ToolContinuationEncodeRequest<'_>,
44 ) -> Result<EncodedExchange, EncodingError> {
45 Err(EncodingError::Unsupported("reject encoder"))
46 }
47}
48
49#[derive(Debug)]
51pub struct EmptyBytesEncoder {
52 pub dialect: DialectDescriptor,
54}
55
56impl EmptyBytesEncoder {
57 pub fn new(dialect: DialectDescriptor) -> Self {
59 Self { dialect }
60 }
61}
62
63impl OutboundDialectEncoder for EmptyBytesEncoder {
64 fn encode_initial(
65 &self,
66 _request: InitialEncodeRequest<'_>,
67 ) -> Result<EncodedExchange, EncodingError> {
68 Ok(EncodedExchange {
69 bytes: Bytes::new(),
70 required_input_dialect: self.dialect.clone(),
71 input_policy: ExchangeInputPolicy::SendAndFinish,
72 })
73 }
74
75 fn encode_tool_continuation(
76 &self,
77 _request: ToolContinuationEncodeRequest<'_>,
78 ) -> Result<EncodedExchange, EncodingError> {
79 Ok(EncodedExchange {
80 bytes: Bytes::new(),
81 required_input_dialect: self.dialect.clone(),
82 input_policy: ExchangeInputPolicy::SendAndFinish,
83 })
84 }
85}
86
87#[derive(Debug, Default)]
93pub struct TestTextEncoder;
94
95impl OutboundDialectEncoder for TestTextEncoder {
96 fn encode_initial(
97 &self,
98 request: InitialEncodeRequest<'_>,
99 ) -> Result<EncodedExchange, EncodingError> {
100 let mut text = String::new();
101 for msg in request.input.messages() {
102 match msg {
103 CanonicalMessage::System { content, .. }
104 | CanonicalMessage::User { content, .. }
105 | CanonicalMessage::Tool { content, .. } => {
106 for part in content {
107 text.push_str(part.text());
108 text.push(' ');
109 }
110 }
111 CanonicalMessage::Assistant { content, .. } => {
112 for part in content {
113 text.push_str(part.text());
114 text.push(' ');
115 }
116 }
117 }
118 }
119 let trimmed = text.trim();
120 if trimmed.is_empty() {
121 return Err(EncodingError::UnrepresentableInput);
122 }
123 let mut body = trimmed.to_string();
124 if !body.ends_with('.') && !body.ends_with('!') && !body.ends_with('?') {
125 body.push('.');
126 }
127 body.push(' ');
128 Ok(EncodedExchange {
129 bytes: Bytes::from(body.into_bytes()),
130 required_input_dialect: DialectDescriptor::test_raw(),
131 input_policy: ExchangeInputPolicy::SendAndFinish,
132 })
133 }
134
135 fn encode_tool_continuation(
136 &self,
137 _request: ToolContinuationEncodeRequest<'_>,
138 ) -> Result<EncodedExchange, EncodingError> {
139 Err(EncodingError::Unsupported(
140 "TestTextEncoder has no tool continuation",
141 ))
142 }
143}