1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use std::path::PathBuf;
use regex::Regex;
use crate::error::{AutoschematicError, AutoschematicErrorType};
use super::r#type::ConnectorType;
pub fn parse_connector_name(name: &str) -> Result<ConnectorType, anyhow::Error> {
// Match a Connector name.
// Connector names take the form:
// {type}:{path}
// Where connector implementations may further interpret `path`
// to enable sub-connector implementations.
// E.G. python:modules/snowflake.py:SnowflakeConnector
let re = Regex::new(r"^(?<type>[^:]+):(?<path>.+)$")?;
let Some(caps) = re.captures(name) else {
return Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
}
.into());
};
match &caps["type"] {
// #[cfg(feature = "python")]
"python" => {
let path = &caps["path"];
let re = Regex::new(r"^(?<python_path>[^:]+):(?<classname>.+)$")?;
let Some(caps) = re.captures(path) else {
return Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
}
.into());
};
let python_path = &caps["python_path"];
let classname = &caps["classname"];
Ok(ConnectorType::Python(python_path.into(), classname.into()))
}
"binary-tarpc" => {
// Run a Connector as sandboxed executable binary over Tarpc.
// Format: "binary:path/of/binary:ConnectorName"
let path = &caps["path"];
let re = Regex::new(r"^(?<binary_path>[^:]+):(?<shortname>.+)$")?;
let Some(caps) = re.captures(path) else {
return Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
}
.into());
};
let binary_path = &caps["binary_path"];
let shortname = &caps["shortname"];
Ok(ConnectorType::BinaryTarpc(
PathBuf::from(binary_path),
shortname.into(),
))
}
"lock" => {
// Format: "lock:EntryName:ConnectorName"
let path = &caps["path"];
let re = Regex::new(r"^(?<entry_name>[^:]+):(?<shortname>.+)$")?;
let Some(caps) = re.captures(path) else {
return Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
}
.into());
};
let entry_name = &caps["entry_name"];
let shortname = &caps["shortname"];
Ok(ConnectorType::LockFile(
PathBuf::from(entry_name),
shortname.into(),
))
}
_ => Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
}
.into()),
}
}
pub fn connector_shortname(name: &str) -> Result<String, AutoschematicError> {
match name {
other => {
// Match a Connector name.
// Connector names take the form:
// {type}:{path}
// Where connector implementations may further interpret `path`
// to enable sub-connector implementations.
// E.G. python:modules/snowflake.py:SnowflakeConnector
let re = Regex::new(r"^(?<type>[^:]+):(?<path>.+)$")?;
let Some(caps) = re.captures(other) else {
return Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
});
};
match &caps["type"] {
#[cfg(feature = "python")]
"python" => Ok("python-custom".into()),
// "dylib" => Ok((
// DylibConnector::new(&caps["path"], prefix, outbox).await?,
// inbox,
// )),
"binary-tarpc" => {
// Run a Connector as sandboxed executable binary over Tarpc.
// Format: "binary:path/of/binary:ConnectorName"
let path = &caps["path"];
let re = Regex::new(r"^(?<binary_path>[^:]+):(?<name>.+)$")?;
let Some(caps) = re.captures(path) else {
return Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
});
};
// let binary_path = &caps["binary_path"];
let name = &caps["name"];
Ok(String::from(name))
}
_ => Err(AutoschematicError {
kind: AutoschematicErrorType::InvalidConnectorString(name.to_string()),
}),
}
}
}
}