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