Skip to main content

spin_world/
lib.rs

1#![allow(missing_docs)]
2#![allow(non_camel_case_types)] // bindgen emits Host_Pre and Host_Indices
3
4pub use async_trait::async_trait;
5
6wasmtime::component::bindgen!({
7    inline: r#"
8    package fermyon:runtime;
9    world host {
10        include fermyon:spin/host;
11        include fermyon:spin/platform@2.0.0;
12        include fermyon:spin/platform@3.0.0;
13        include spin:up/platform@3.2.0;
14        include spin:up/platform@3.4.0;
15        include spin:up/platform@3.7.0;
16        include wasi:keyvalue/imports@0.2.0-draft2;
17    }
18    "#,
19    path: "../../wit",
20    imports: { default: async | trappable },
21    exports: { default: async },
22    // The following is a roundabout way of saying "the host implementations for these interfaces don't trap"
23    trappable_error_type: {
24        "fermyon:spin/config.error" => v1::config::Error,
25        "fermyon:spin/http-types.http-error" => v1::http_types::HttpError,
26        "fermyon:spin/llm@2.0.0.error" => v2::llm::Error,
27        "fermyon:spin/llm.error" => v1::llm::Error,
28        "fermyon:spin/mqtt@2.0.0.error" => v2::mqtt::Error,
29        "fermyon:spin/mysql.mysql-error" => v1::mysql::MysqlError,
30        "fermyon:spin/postgres.pg-error" => v1::postgres::PgError,
31        "fermyon:spin/rdbms-types@2.0.0.error" => v2::rdbms_types::Error,
32        "fermyon:spin/redis-types.error" => v1::redis_types::Error,
33        "fermyon:spin/redis@2.0.0.error" => v2::redis::Error,
34        "fermyon:spin/sqlite@2.0.0.error" => v2::sqlite::Error,
35        "fermyon:spin/sqlite.error" => v1::sqlite::Error,
36        "fermyon:spin/variables@2.0.0.error" => v2::variables::Error,
37        "spin:postgres/postgres@3.0.0.error" => spin::postgres3_0_0::postgres::Error,
38        "spin:postgres/postgres@4.2.0.error" => spin::postgres4_2_0::postgres::Error,
39        "spin:sqlite/sqlite@3.1.0.error" => spin::sqlite3_1_0::sqlite::Error,
40        "wasi:config/store@0.2.0-draft-2024-09-27.error" => wasi::config::store::Error,
41        "wasi:keyvalue/store.error" => wasi::keyvalue::store::Error,
42        "wasi:keyvalue/atomics.cas-error" => wasi::keyvalue::atomics::CasError,
43    },
44    anyhow: true,
45});
46
47pub use fermyon::spin as v1;
48pub use fermyon::spin2_0_0 as v2;
49
50mod conversions;
51pub mod wasi_otel;
52
53/// Maximum allowed size of a host-buffered database query result, HTTP request
54/// or response body, or similar.
55///
56/// If and when Spin encounters content larger than this
57// TODO: make this configurable
58pub const MAX_HOST_BUFFERED_BYTES: usize = 128 << 20;
59
60impl spin::sqlite3_1_0::sqlite::Value {
61    pub fn memory_size(&self) -> usize {
62        match self {
63            Self::Null | Self::Integer(_) | Self::Real(_) => std::mem::size_of::<Self>(),
64            Self::Text(t) => std::mem::size_of::<Self>() + t.len(),
65            Self::Blob(b) => std::mem::size_of::<Self>() + b.len(),
66        }
67    }
68}
69
70impl spin::postgres4_2_0::postgres::DbValue {
71    pub fn memory_size(&self) -> usize {
72        match self {
73            Self::DbNull
74            | Self::Boolean(_)
75            | Self::Int8(_)
76            | Self::Int16(_)
77            | Self::Int32(_)
78            | Self::Int64(_)
79            | Self::Floating32(_)
80            | Self::Floating64(_)
81            | Self::Date(_)
82            | Self::Time(_)
83            | Self::Datetime(_)
84            | Self::Timestamp(_)
85            | Self::RangeInt32(_)
86            | Self::RangeInt64(_)
87            | Self::RangeDecimal(_)
88            | Self::Interval(_) => std::mem::size_of::<Self>(),
89            Self::ArrayInt32(v) => {
90                std::mem::size_of::<Self>() + (v.len() * std::mem::size_of::<Option<i32>>())
91            }
92            Self::ArrayInt64(v) => {
93                std::mem::size_of::<Self>() + (v.len() * std::mem::size_of::<Option<i64>>())
94            }
95            Self::ArrayDecimal(v) | Self::ArrayStr(v) => {
96                std::mem::size_of::<Self>()
97                    + v.iter()
98                        .map(|v| {
99                            std::mem::size_of::<Option<String>>()
100                                + v.as_ref().map(|s| s.len()).unwrap_or(0)
101                        })
102                        .sum::<usize>()
103            }
104            Self::Str(s) | Self::Uuid(s) | Self::Decimal(s) => {
105                std::mem::size_of::<Self>() + s.len()
106            }
107            Self::Jsonb(b) | Self::Binary(b) | Self::Unsupported(b) => {
108                std::mem::size_of::<Self>() + b.len()
109            }
110        }
111    }
112}
113
114impl v2::rdbms_types::DbValue {
115    pub fn memory_size(&self) -> usize {
116        match self {
117            Self::DbNull
118            | Self::Unsupported
119            | Self::Boolean(_)
120            | Self::Int8(_)
121            | Self::Int16(_)
122            | Self::Int32(_)
123            | Self::Int64(_)
124            | Self::Uint8(_)
125            | Self::Uint16(_)
126            | Self::Uint32(_)
127            | Self::Uint64(_)
128            | Self::Floating32(_)
129            | Self::Floating64(_) => std::mem::size_of::<Self>(),
130            Self::Str(s) => std::mem::size_of::<Self>() + s.len(),
131            Self::Binary(b) => std::mem::size_of::<Self>() + b.len(),
132        }
133    }
134}