a3s_code_core/capability/
effect.rs1use async_trait::async_trait;
2use thiserror::Error;
3
4const MAX_EFFECT_ERROR_BYTES: usize = 1_024;
5
6#[derive(Clone, Debug, Eq, Error, PartialEq)]
8#[error("{message}")]
9pub struct CapabilityEffectError {
10 message: Box<str>,
11}
12
13impl CapabilityEffectError {
14 pub fn new(message: impl Into<String>) -> Self {
15 let message = message.into();
16 let message = if message.is_empty() {
17 "capability effect teardown failed".to_owned()
18 } else {
19 truncate_utf8(message, MAX_EFFECT_ERROR_BYTES)
20 };
21 Self {
22 message: message.into_boxed_str(),
23 }
24 }
25
26 pub fn message(&self) -> &str {
27 &self.message
28 }
29}
30
31#[async_trait]
39pub trait CapabilityEffect: Send + 'static {
40 fn name(&self) -> &str;
41
42 async fn close(self: Box<Self>) -> Result<(), CapabilityEffectError>;
43}
44
45fn truncate_utf8(mut value: String, max: usize) -> String {
46 if value.len() <= max {
47 return value;
48 }
49 let mut boundary = max;
50 while !value.is_char_boundary(boundary) {
51 boundary -= 1;
52 }
53 value.truncate(boundary);
54 value
55}