mirror of
https://github.com/Noratrieb/terustform.git
synced 2026-01-14 16:35:11 +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::{
|
use terustform::{
|
||||||
datasource::{self, DataSource},
|
datasource::{self, DataSource},
|
||||||
provider::Provider,
|
provider::Provider,
|
||||||
values::Value,
|
AttrPath, DResult, StringValue, Value, ValueModel,
|
||||||
AttrPath, DResult, StringValue, ValueModel,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::values::{Value, ValueKind};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Diagnostics {
|
pub struct Diagnostics {
|
||||||
pub(crate) diags: Vec<Diagnostic>,
|
pub(crate) diags: Vec<Diagnostic>,
|
||||||
|
|
@ -14,6 +12,18 @@ pub struct Diagnostic {
|
||||||
|
|
||||||
pub type DResult<T> = Result<T, Diagnostics>;
|
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 {
|
impl Diagnostic {
|
||||||
pub fn error_string(msg: impl Into<String>) -> Self {
|
pub fn error_string(msg: impl Into<String>) -> Self {
|
||||||
Diagnostic {
|
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 {
|
impl<E: std::error::Error + std::fmt::Debug> From<E> for Diagnostic {
|
||||||
fn from(value: E) -> Self {
|
fn from(value: E) -> Self {
|
||||||
Self::error_string(format!("{:?}", value))
|
Self::error_string(format!("{:?}", value))
|
||||||
|
|
@ -49,93 +73,3 @@ impl From<Diagnostic> for Diagnostics {
|
||||||
Self { diags: vec![value] }
|
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 datasource;
|
||||||
pub mod provider;
|
pub mod provider;
|
||||||
mod server;
|
|
||||||
pub mod values;
|
|
||||||
|
|
||||||
pub use base::*;
|
pub use diag::*;
|
||||||
pub use terustform_macros::Model;
|
pub use terustform_macros::Model;
|
||||||
|
pub use values::*;
|
||||||
|
|
||||||
use provider::Provider;
|
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.
|
/// Private, only for use for with the derive macro.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod __derive_private {
|
pub mod __derive_private {
|
||||||
pub use crate::values::{Value, ValueKind};
|
|
||||||
pub use crate::{
|
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};
|
pub use {Clone, Option::Some, Result::Err, ToOwned};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
io::{self, Read},
|
io::{self, Read},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{BaseValue, DResult, Diagnostic};
|
use crate::{AttrPath, DResult, Diagnostic};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Type {
|
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
|
// marshal msg pack
|
||||||
// tftypes/value.go:MarshalMsgPack
|
// tftypes/value.go:MarshalMsgPack
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue