mirror of
https://github.com/Noratrieb/terustform.git
synced 2026-01-14 08:30:13 +01:00
more movement
This commit is contained in:
parent
7e479e7a28
commit
991642b90d
4 changed files with 100 additions and 101 deletions
|
|
@ -3,8 +3,7 @@ use std::collections::HashMap;
|
|||
use terustform::{
|
||||
datasource::{self, DataSource},
|
||||
provider::Provider,
|
||||
values::Value,
|
||||
AttrPath, DResult, StringValue, ValueModel,
|
||||
AttrPath, DResult, StringValue, Value, ValueModel,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use crate::values::{Value, ValueKind};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Diagnostics {
|
||||
pub(crate) diags: Vec<Diagnostic>,
|
||||
|
|
@ -14,6 +12,18 @@ pub struct Diagnostic {
|
|||
|
||||
pub type DResult<T> = Result<T, Diagnostics>;
|
||||
|
||||
// TODO: this could probably be a clever 0-alloc &-based linked list!
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct AttrPath(pub(crate) Vec<AttrPathSegment>);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AttrPathSegment {
|
||||
AttributeName(String),
|
||||
ElementKeyString(String),
|
||||
ElementKeyInt(i64),
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
pub fn error_string(msg: impl Into<String>) -> Self {
|
||||
Diagnostic {
|
||||
|
|
@ -33,6 +43,20 @@ impl Diagnostics {
|
|||
}
|
||||
}
|
||||
|
||||
impl AttrPath {
|
||||
pub fn root() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
pub fn attr(name: impl Into<String>) -> Self {
|
||||
Self(vec![AttrPathSegment::AttributeName(name.into())])
|
||||
}
|
||||
pub fn append_attribute_name(&self, name: String) -> Self {
|
||||
let mut p = self.clone();
|
||||
p.0.push(AttrPathSegment::AttributeName(name));
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: std::error::Error + std::fmt::Debug> From<E> for Diagnostic {
|
||||
fn from(value: E) -> Self {
|
||||
Self::error_string(format!("{:?}", value))
|
||||
|
|
@ -49,93 +73,3 @@ impl From<Diagnostic> for Diagnostics {
|
|||
Self { diags: vec![value] }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this could probably be a clever 0-alloc &-based linked list!
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct AttrPath(pub(crate) Vec<AttrPathSegment>);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AttrPathSegment {
|
||||
AttributeName(String),
|
||||
ElementKeyString(String),
|
||||
ElementKeyInt(i64),
|
||||
}
|
||||
|
||||
impl AttrPath {
|
||||
pub fn root() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
pub fn attr(name: impl Into<String>) -> Self {
|
||||
Self(vec![AttrPathSegment::AttributeName(name.into())])
|
||||
}
|
||||
pub fn append_attribute_name(&self, name: String) -> Self {
|
||||
let mut p = self.clone();
|
||||
p.0.push(AttrPathSegment::AttributeName(name));
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
pub type StringValue = BaseValue<String>;
|
||||
pub type I64Value = BaseValue<i64>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BaseValue<T> {
|
||||
Unknown,
|
||||
Null,
|
||||
Known(T),
|
||||
}
|
||||
|
||||
impl<T> BaseValue<T> {
|
||||
fn map<U>(self, f: impl FnOnce(T) -> U) -> BaseValue<U> {
|
||||
self.try_map(|v| Ok(f(v))).unwrap()
|
||||
}
|
||||
|
||||
fn try_map<U>(self, f: impl FnOnce(T) -> DResult<U>) -> DResult<BaseValue<U>> {
|
||||
Ok(match self {
|
||||
Self::Unknown => BaseValue::Unknown,
|
||||
Self::Null => BaseValue::Null,
|
||||
Self::Known(v) => BaseValue::Known(f(v)?),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expect_known(&self, path: AttrPath) -> DResult<&T> {
|
||||
match self {
|
||||
BaseValue::Null => Err(Diagnostic::error_string("expected value, found null value")
|
||||
.with_path(path)
|
||||
.into()),
|
||||
BaseValue::Unknown => Err(Diagnostic::error_string(
|
||||
"expected known value, found unknown value",
|
||||
)
|
||||
.with_path(path)
|
||||
.into()),
|
||||
BaseValue::Known(v) => Ok(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ValueModel: Sized {
|
||||
fn from_value(v: Value, path: &AttrPath) -> DResult<Self>;
|
||||
|
||||
fn to_value(self) -> Value;
|
||||
}
|
||||
|
||||
impl ValueModel for StringValue {
|
||||
fn from_value(v: Value, path: &AttrPath) -> DResult<Self> {
|
||||
v.try_map(|v| -> DResult<String> {
|
||||
match v {
|
||||
ValueKind::String(s) => Ok(s),
|
||||
_ => Err(Diagnostic::error_string(format!(
|
||||
"expected string, found {}",
|
||||
v.diagnostic_type_str()
|
||||
))
|
||||
.with_path(path.clone())
|
||||
.into()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn to_value(self) -> Value {
|
||||
self.map(ValueKind::String)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
mod base;
|
||||
mod diag;
|
||||
mod server;
|
||||
mod values;
|
||||
|
||||
pub mod datasource;
|
||||
pub mod provider;
|
||||
mod server;
|
||||
pub mod values;
|
||||
|
||||
pub use base::*;
|
||||
pub use diag::*;
|
||||
pub use terustform_macros::Model;
|
||||
pub use values::*;
|
||||
|
||||
use provider::Provider;
|
||||
|
||||
|
|
@ -24,9 +26,9 @@ pub async fn start(provider: &dyn Provider) -> eyre::Result<()> {
|
|||
/// Private, only for use for with the derive macro.
|
||||
#[doc(hidden)]
|
||||
pub mod __derive_private {
|
||||
pub use crate::values::{Value, ValueKind};
|
||||
pub use crate::{
|
||||
AttrPath, AttrPathSegment, BaseValue, DResult, Diagnostic, Diagnostics, ValueModel,
|
||||
AttrPath, AttrPathSegment, BaseValue, DResult, Diagnostic, Diagnostics, Value, ValueKind,
|
||||
ValueModel,
|
||||
};
|
||||
pub use {Clone, Option::Some, Result::Err, ToOwned};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
io::{self, Read},
|
||||
};
|
||||
|
||||
use crate::{BaseValue, DResult, Diagnostic};
|
||||
use crate::{AttrPath, DResult, Diagnostic};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Type {
|
||||
|
|
@ -108,6 +108,70 @@ impl ValueKind {
|
|||
}
|
||||
}
|
||||
|
||||
pub type StringValue = BaseValue<String>;
|
||||
pub type I64Value = BaseValue<i64>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BaseValue<T> {
|
||||
Unknown,
|
||||
Null,
|
||||
Known(T),
|
||||
}
|
||||
|
||||
impl<T> BaseValue<T> {
|
||||
fn map<U>(self, f: impl FnOnce(T) -> U) -> BaseValue<U> {
|
||||
self.try_map(|v| Ok(f(v))).unwrap()
|
||||
}
|
||||
|
||||
fn try_map<U>(self, f: impl FnOnce(T) -> DResult<U>) -> DResult<BaseValue<U>> {
|
||||
Ok(match self {
|
||||
Self::Unknown => BaseValue::Unknown,
|
||||
Self::Null => BaseValue::Null,
|
||||
Self::Known(v) => BaseValue::Known(f(v)?),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expect_known(&self, path: AttrPath) -> DResult<&T> {
|
||||
match self {
|
||||
BaseValue::Null => Err(Diagnostic::error_string("expected value, found null value")
|
||||
.with_path(path)
|
||||
.into()),
|
||||
BaseValue::Unknown => Err(Diagnostic::error_string(
|
||||
"expected known value, found unknown value",
|
||||
)
|
||||
.with_path(path)
|
||||
.into()),
|
||||
BaseValue::Known(v) => Ok(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ValueModel: Sized {
|
||||
fn from_value(v: Value, path: &AttrPath) -> DResult<Self>;
|
||||
|
||||
fn to_value(self) -> Value;
|
||||
}
|
||||
|
||||
impl ValueModel for StringValue {
|
||||
fn from_value(v: Value, path: &AttrPath) -> DResult<Self> {
|
||||
v.try_map(|v| -> DResult<String> {
|
||||
match v {
|
||||
ValueKind::String(s) => Ok(s),
|
||||
_ => Err(Diagnostic::error_string(format!(
|
||||
"expected string, found {}",
|
||||
v.diagnostic_type_str()
|
||||
))
|
||||
.with_path(path.clone())
|
||||
.into()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn to_value(self) -> Value {
|
||||
self.map(ValueKind::String)
|
||||
}
|
||||
}
|
||||
|
||||
// marshal msg pack
|
||||
// tftypes/value.go:MarshalMsgPack
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue