I am trying to create a library which gets Values for multiple Tags from an SQL Database. Depending on the TagType which can be Analog or String - I need to return the matching value type. I tried to achieve this using a associated type named ValueType
in the Tag
trait
This is what i have got until now:
use sqlx::Row;
pub trait Tag {
type ValueType;
fn name(&self) -> String;
fn tagtype(&self) -> TagType;
}
pub enum TagType {
Analog = 1,
String = 3,
}
pub struct AnalogTag(String);
pub struct StringTag(String);
impl Tag for AnalogTag {
type ValueType = f64;
fn name(&self) -> String {
self.0.to_string()
}
fn tagtype(&self) -> TagType {
TagType::Analog
}
}
impl Tag for StringTag {
type ValueType = String;
fn name(&self) -> String {
self.0.to_string()
}
fn tagtype(&self) -> TagType {
TagType::String
}
}
pub struct Value<T> {
pub val: T,
pub quality: i8,
}
impl<T> Value<T> {
fn new(val: T, quality: i8) -> Self {
Self { val, quality }
}
}
pub async fn get_actual_value<T: Tag>(
db_pool: sqlx::MssqlPool,
tag: T,
) -> Result<Value<T::ValueType>, sqlx::Error> {
let table = match tag.tagtype() {
TagType::Analog => "AnalogLive",
TagType::String => "StringLive",
};
let result = sqlx::query("SELECT Value, Quality FROM @P1 WHERE Tagname = @P2")
.bind(table)
.bind(tag.name())
.fetch_one(&db_pool)
.await?;
let val = result.get("Value");
let quality: i8 = result.get("Quality");
Ok(Value::new(val, quality))
}
Anyhow, this will not work.
I need to implement sqlx::Decode
and Type<Mssql>
traits but don't know how this can be done for ValueType
that is an associated type of the trait Tag
the trait
sqlx::Decode<'_, Mssql>
is not implemented for<T as Tag>::ValueType
the traitType<Mssql>
is not implemented for<T as Tag>::ValueType
Any help would be appreciated!
EDIT Updated the code-example to a minimal reproducible example