golem-schema 1.6.1

Golem schema and value model
Documentation
// Copyright 2024-2026 Golem Cloud
//
// Licensed under the Golem Source License v1.1 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://license.golem.cloud/LICENSE
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::{FromSchema, FromSchemaError, IntoSchema, SchemaBuilder, value_kind};
use crate::schema::metadata::TypeId;
use crate::schema::schema_type::SchemaType;
use crate::schema::schema_value::{DurationValuePayload, SchemaValue};

#[cfg(feature = "guest")]
impl crate::schema::wit::direct::WireSchema for ::chrono::Duration {
    fn wire_type_id() -> String {
        <Self as IntoSchema>::type_id().0
    }

    fn append_schema(builder: &mut crate::schema::wit::direct::WireSchemaBuilder) -> i32 {
        builder.push(crate::schema::wit::wire::SchemaTypeBody::DurationType)
    }
}

#[cfg(feature = "guest")]
impl crate::schema::wit::direct::IntoWire for ::chrono::Duration {
    const NEEDS_PREPARATION: bool = false;

    fn write_wire(
        &self,
        writer: &mut crate::schema::wit::direct::WireWriter,
    ) -> Result<i32, crate::schema::wit::direct::WireError> {
        Ok(
            writer.push(crate::schema::wit::wire::SchemaValueNode::DurationValue(
                crate::schema::wit::wire::DurationValuePayload {
                    nanoseconds: self
                        .num_nanoseconds()
                        .unwrap_or(self.num_seconds() * 1_000_000_000),
                },
            )),
        )
    }
}

#[cfg(feature = "guest")]
impl crate::schema::wit::direct::FromWire for ::chrono::Duration {
    fn read_wire(
        reader: &mut crate::schema::wit::direct::WireReader,
        index: i32,
    ) -> Result<Self, crate::schema::wit::direct::WireError> {
        match reader.take(index)? {
            crate::schema::wit::wire::SchemaValueNode::DurationValue(value) => {
                Ok(Self::nanoseconds(value.nanoseconds))
            }
            _ => Err(crate::schema::wit::direct::WireError::Shape("duration")),
        }
    }
}

impl IntoSchema for ::chrono::Duration {
    fn type_id() -> TypeId {
        TypeId::new("chrono.Duration")
    }
    fn register_in(_b: &mut SchemaBuilder) -> SchemaType {
        SchemaType::duration()
    }
    fn to_value(&self) -> SchemaValue {
        SchemaValue::Duration(DurationValuePayload {
            nanoseconds: self
                .num_nanoseconds()
                .unwrap_or(self.num_seconds() * 1_000_000_000),
        })
    }
}

impl FromSchema for ::chrono::Duration {
    fn from_value(v: &SchemaValue) -> Result<Self, FromSchemaError> {
        match v {
            SchemaValue::Duration(p) => Ok(::chrono::Duration::nanoseconds(p.nanoseconds)),
            other => Err(FromSchemaError::shape_mismatch(
                "duration",
                value_kind(other),
                "chrono::Duration",
            )),
        }
    }
}

const NAIVE_DATE_FMT: &str = "%Y-%m-%d";
const NAIVE_DATE_TIME_FMT: &str = "%Y-%m-%dT%H:%M:%S%.9f";
const NAIVE_TIME_FMT: &str = "%H:%M:%S%.9f";

#[cfg(feature = "guest")]
crate::schema::wit::direct::wire_string!(
    ::chrono::NaiveDate,
    |value: &::chrono::NaiveDate| value.format(NAIVE_DATE_FMT).to_string(),
    |value: &str| ::chrono::NaiveDate::parse_from_str(value, NAIVE_DATE_FMT)
);
#[cfg(feature = "guest")]
crate::schema::wit::direct::wire_string!(
    ::chrono::NaiveDateTime,
    |value: &::chrono::NaiveDateTime| value.format(NAIVE_DATE_TIME_FMT).to_string(),
    |value: &str| ::chrono::NaiveDateTime::parse_from_str(value, NAIVE_DATE_TIME_FMT)
);
#[cfg(feature = "guest")]
crate::schema::wit::direct::wire_string!(
    ::chrono::NaiveTime,
    |value: &::chrono::NaiveTime| value.format(NAIVE_TIME_FMT).to_string(),
    |value: &str| ::chrono::NaiveTime::parse_from_str(value, NAIVE_TIME_FMT)
);

impl IntoSchema for ::chrono::NaiveDate {
    fn type_id() -> TypeId {
        TypeId::new("chrono.NaiveDate")
    }
    fn register_in(_b: &mut SchemaBuilder) -> SchemaType {
        SchemaType::string()
    }
    fn to_value(&self) -> SchemaValue {
        SchemaValue::String(self.format(NAIVE_DATE_FMT).to_string())
    }
}

impl FromSchema for ::chrono::NaiveDate {
    fn from_value(v: &SchemaValue) -> Result<Self, FromSchemaError> {
        match v {
            SchemaValue::String(s) => ::chrono::NaiveDate::parse_from_str(s, NAIVE_DATE_FMT)
                .map_err(|e| FromSchemaError::custom(format!("invalid NaiveDate: {e}"))),
            other => Err(FromSchemaError::shape_mismatch(
                "string",
                value_kind(other),
                "NaiveDate",
            )),
        }
    }
}

impl IntoSchema for ::chrono::NaiveDateTime {
    fn type_id() -> TypeId {
        TypeId::new("chrono.NaiveDateTime")
    }
    fn register_in(_b: &mut SchemaBuilder) -> SchemaType {
        SchemaType::string()
    }
    fn to_value(&self) -> SchemaValue {
        SchemaValue::String(self.format(NAIVE_DATE_TIME_FMT).to_string())
    }
}

impl FromSchema for ::chrono::NaiveDateTime {
    fn from_value(v: &SchemaValue) -> Result<Self, FromSchemaError> {
        match v {
            SchemaValue::String(s) => {
                ::chrono::NaiveDateTime::parse_from_str(s, NAIVE_DATE_TIME_FMT)
                    .map_err(|e| FromSchemaError::custom(format!("invalid NaiveDateTime: {e}")))
            }
            other => Err(FromSchemaError::shape_mismatch(
                "string",
                value_kind(other),
                "NaiveDateTime",
            )),
        }
    }
}

impl IntoSchema for ::chrono::NaiveTime {
    fn type_id() -> TypeId {
        TypeId::new("chrono.NaiveTime")
    }
    fn register_in(_b: &mut SchemaBuilder) -> SchemaType {
        SchemaType::string()
    }
    fn to_value(&self) -> SchemaValue {
        SchemaValue::String(self.format(NAIVE_TIME_FMT).to_string())
    }
}

impl FromSchema for ::chrono::NaiveTime {
    fn from_value(v: &SchemaValue) -> Result<Self, FromSchemaError> {
        match v {
            SchemaValue::String(s) => ::chrono::NaiveTime::parse_from_str(s, NAIVE_TIME_FMT)
                .map_err(|e| FromSchemaError::custom(format!("invalid NaiveTime: {e}"))),
            other => Err(FromSchemaError::shape_mismatch(
                "string",
                value_kind(other),
                "NaiveTime",
            )),
        }
    }
}