marine/fluence-faas/src/faas_interface.rs

182 lines
5.5 KiB
Rust
Raw Normal View History

2020-06-10 16:55:18 +03:00
/*
* Copyright 2020 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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::IType;
2020-09-16 01:14:15 +03:00
use super::IRecordType;
use super::IFunctionArg;
2020-08-07 11:54:37 +03:00
use serde::Serialize;
use serde::Serializer;
2020-06-10 16:55:18 +03:00
use std::fmt;
use std::collections::HashMap;
2020-09-16 13:46:38 +03:00
use itertools::Itertools;
2020-06-10 16:55:18 +03:00
2020-08-25 19:26:21 +03:00
#[derive(Debug, PartialEq, Clone)]
pub struct FaaSInterface<'a> {
2020-09-16 01:14:15 +03:00
pub record_types: HashMap<u64, &'a IRecordType>,
pub modules: HashMap<&'a str, HashMap<&'a str, FaaSFunctionSignature<'a>>>,
}
2020-08-25 19:26:21 +03:00
#[derive(Debug, PartialEq, Clone)]
pub struct FaaSFunctionSignature<'a> {
2020-09-16 01:14:15 +03:00
pub arguments: &'a Vec<IFunctionArg>,
pub output_types: &'a Vec<IType>,
2020-06-10 16:55:18 +03:00
}
impl<'a> fmt::Display for FaaSInterface<'a> {
2020-06-10 16:55:18 +03:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2020-09-16 01:14:15 +03:00
let type_text_view = |arg_ty: &IType| {
match arg_ty {
IType::Record(record_type_id) => {
// unwrap is safe because FaasInterface here is well-formed
// (it was checked on the module startup stage)
let record = self.record_types.get(record_type_id).unwrap();
record.name.clone()
}
t => format!("{:?}", t),
}
};
for (_, record_type) in self.record_types.iter() {
writeln!(f, "{} {{", record_type.name)?;
for field in record_type.fields.iter() {
2020-09-16 12:31:21 +03:00
writeln!(f, " {}: {}", field.name, type_text_view(&field.ty))?;
2020-09-16 01:14:15 +03:00
}
writeln!(f, "}}")?;
}
if !self.record_types.is_empty() {
writeln!(f)?;
}
for (name, functions) in self.modules.iter() {
2020-09-16 12:31:21 +03:00
writeln!(f, "\n{}:", *name)?;
for (name, signature) in functions.iter() {
2020-09-23 01:14:54 +03:00
write!(f, " fn {}(", name)?;
2020-09-16 01:14:15 +03:00
2020-09-16 13:46:38 +03:00
let args = signature
.arguments
.iter()
.map(|arg| format!("{}: {}", arg.name, type_text_view(&arg.ty)))
.join(", ");
2020-09-16 01:14:15 +03:00
if signature.output_types.is_empty() {
2020-09-16 13:46:38 +03:00
writeln!(f, "{})", args)?;
2020-09-16 01:14:15 +03:00
} else if signature.output_types.len() == 1 {
2020-09-16 13:46:38 +03:00
writeln!(
f,
"{}) -> {}",
args,
type_text_view(&signature.output_types[0])
)?;
2020-09-16 01:14:15 +03:00
} else {
// At now, multi values aren't supported - only one output type is possible
unimplemented!()
}
}
2020-06-10 16:55:18 +03:00
}
Ok(())
}
}
2020-07-28 16:29:09 +03:00
impl<'a> Serialize for FaaSInterface<'a> {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
#[derive(Serialize)]
pub struct Function<'a> {
pub name: &'a str,
2020-09-16 01:14:15 +03:00
pub arguments: Vec<(&'a String, &'a IType)>,
2020-07-28 16:29:09 +03:00
pub output_types: &'a Vec<IType>,
}
2020-09-16 01:14:15 +03:00
#[derive(Serialize)]
pub struct RecordType<'a> {
pub name: &'a str,
pub id: u64,
pub fields: Vec<(&'a String, &'a IType)>,
}
2020-07-28 16:29:09 +03:00
#[derive(Serialize)]
pub struct Module<'a> {
pub name: &'a str,
pub functions: Vec<Function<'a>>,
}
#[derive(Serialize)]
pub struct Interface<'a> {
2020-09-16 01:14:15 +03:00
pub record_types: Vec<RecordType<'a>>,
2020-07-28 16:29:09 +03:00
pub modules: Vec<Module<'a>>,
}
2020-09-16 01:14:15 +03:00
let record_types: Vec<_> = self
.record_types
.iter()
.map(|(id, IRecordType { name, fields })| {
let fields = fields
.iter()
.map(|field| (&field.name, &field.ty))
.collect::<Vec<_>>();
RecordType {
name: name.as_str(),
id: *id,
fields,
}
})
.collect();
2020-07-28 16:29:09 +03:00
let modules: Vec<_> = self
.modules
.iter()
.map(|(name, functions)| {
let functions = functions
.iter()
.map(
|(
name,
FaaSFunctionSignature {
2020-09-16 01:14:15 +03:00
arguments,
2020-07-28 16:29:09 +03:00
output_types,
},
)| {
2020-09-16 01:14:15 +03:00
let arguments =
arguments.iter().map(|arg| (&arg.name, &arg.ty)).collect();
2020-07-28 16:29:09 +03:00
Function {
name,
2020-09-16 01:14:15 +03:00
arguments,
2020-07-28 16:29:09 +03:00
output_types,
}
},
)
.collect();
Module { name, functions }
})
.collect();
2020-09-16 01:14:15 +03:00
Interface {
record_types,
modules,
}
.serialize(serializer)
2020-07-28 16:29:09 +03:00
}
}