Skip to content

Commit

Permalink
some more implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
amitu committed Nov 12, 2024
1 parent de9e5a1 commit 22ae86a
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 41 deletions.
11 changes: 11 additions & 0 deletions v0.5/fastn-section/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ impl fastn_section::Section {
.as_ref()
.and_then(|c| c.as_plain_string(source))
}

pub fn header_as_plain_string<'input>(
&self,
source: &'input str,
name: &str,
) -> Option<&'input str> {
self.headers
.iter()
.find(|h| h.name(source) == name)
.and_then(|h| h.value.as_plain_string(source))
}
}

impl fastn_section::HeaderValue {
Expand Down
36 changes: 29 additions & 7 deletions v0.5/fastn-unresolved/src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
impl fastn_section::JDebug for fastn_unresolved::Import {
fn debug(&self, _source: &str) -> serde_json::Value {
fn debug(&self, source: &str) -> serde_json::Value {
let mut o = serde_json::Map::new();

let name = if self.package.0.is_empty() {
Expand All @@ -17,12 +17,34 @@ impl fastn_section::JDebug for fastn_unresolved::Import {
.into(),
);

// if let Some(ref v) = self.exports {
// o.insert("exports".into(), v.debug(source));
// }
// if let Some(ref v) = self.exposing {
// o.insert("exposing".into(), v.debug(source));
// }
if let Some(ref v) = self.export {
o.insert("exports".into(), v.debug(source));
}

if let Some(ref v) = self.exposing {
o.insert("exposing".into(), v.debug(source));
}
serde_json::Value::Object(o)
}
}

impl fastn_section::JDebug for fastn_unresolved::Export {
fn debug(&self, source: &str) -> serde_json::Value {
match self {
fastn_unresolved::Export::All => "all".into(),
fastn_unresolved::Export::Things(v) => {
serde_json::Value::Array(v.iter().map(|v| v.debug(source)).collect())
}
}
}
}

impl fastn_section::JDebug for fastn_unresolved::AliasableIdentifier {
fn debug(&self, _source: &str) -> serde_json::Value {
match self.alias {
Some(ref v) => format!("{}=>{}", self.name.0, v.0),
None => self.name.0.to_string(),
}
.into()
}
}
2 changes: 1 addition & 1 deletion v0.5/fastn-unresolved/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub struct Import {
pub package: PackageName,
pub module: ModuleName,
pub alias: Option<Identifier>,
pub exports: Option<Export>,
pub export: Option<Export>,
pub exposing: Option<Export>,
}

Expand Down
84 changes: 51 additions & 33 deletions v0.5/fastn-unresolved/src/parser/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,14 @@ pub(super) fn import(
// we will go ahead with this import statement parsing
}

let caption = match section.caption_as_plain_string(source) {
Some(v) => v,
None => {
document.errors.push(
section
.span()
.wrap(fastn_section::Error::ImportMustHaveCaption),
);
return;
}
};

let mut i = match parse_module_name(caption, document) {
let i = match parse_import(&section, source, document) {
Some(v) => v,
None => {
// error handling is job of parse_module_name().
return;
}
};

// only two headers allowed: exports and exposing, unresolved them.
parse_export(source, &section, document, &mut i);
parse_exposing(source, &section, document, &mut i);

// ensure there are no extra headers, children or body
fastn_unresolved::utils::assert_no_body(&section, document);
fastn_unresolved::utils::assert_no_sub_sections(&section, document);
Expand All @@ -59,10 +43,23 @@ pub(super) fn import(
document.imports.push(i);
}

fn parse_module_name(
caption: &str,
_document: &mut fastn_unresolved::Document,
fn parse_import(
section: &fastn_section::Section,
source: &str,
document: &mut fastn_unresolved::Document,
) -> Option<fastn_unresolved::Import> {
let caption = match section.caption_as_plain_string(source) {
Some(v) => v,
None => {
document.errors.push(
section
.span()
.wrap(fastn_section::Error::ImportMustHaveCaption),
);
return None;
}
};

// section.caption must be single text block, parsable as a module-name.
// module-name must be internally able to handle aliasing.
let (module, alias) = match caption.split_once(" as ") {
Expand All @@ -79,25 +76,34 @@ fn parse_module_name(
package: fastn_unresolved::PackageName(package.to_string()),
module: fastn_unresolved::ModuleName(module.to_string()),
alias: alias.map(|v| fastn_unresolved::Identifier(v.to_string())),
exports: None,
exposing: None,
export: parse_field("export", source, section, document),
exposing: parse_field("exposing", source, section, document),
})
}

fn parse_export(
_source: &str,
_section: &fastn_section::Section,
fn parse_field(
field: &str,
source: &str,
section: &fastn_section::Section,
_document: &mut fastn_unresolved::Document,
_import: &mut fastn_unresolved::Import,
) {
) -> Option<fastn_unresolved::Export> {
let header = match section.header_as_plain_string(field, source) {
Some(v) => v,
None => return None,
};

Some(fastn_unresolved::Export::Things(
header.split(",").map(aliasable).collect(),
))
}

fn parse_exposing(
_source: &str,
_section: &fastn_section::Section,
_document: &mut fastn_unresolved::Document,
_import: &mut fastn_unresolved::Import,
) {
fn aliasable(s: &str) -> fastn_unresolved::AliasableIdentifier {
let (name, alias) = match s.split_once(" as ") {
Some((name, alias)) => (name.into(), Some(alias.into())),
None => (s.into(), None),
};

fastn_unresolved::AliasableIdentifier { name, alias }
}

#[cfg(test)]
Expand Down Expand Up @@ -131,6 +137,18 @@ mod tests {
t!("-- import: foo as f", { "import": "foo=>f" });
t!("-- import: foo as f\nexposing: x", { "import": "foo=>f", "exposing": ["x"] });
t!("-- import: foo\nexposing: x", { "import": "foo", "exposing": ["x"] });
t!("-- import: foo\nexposing: x, y, z", { "import": "foo", "exposing": ["x", "y", "z"] });
t!("-- import: foo as f\nexposing: x as y", { "import": "foo as f", "exposing": ["x=>y"] });
t!("-- import: foo as f\nexposing: x as y, z", { "import": "foo as f", "exposing": ["x=>y", "z"] });
t!("-- import: foo as f\nexport: x", { "import": "foo=>f", "export": ["x"] });
t!("-- import: foo\nexport: x", { "import": "foo", "export": ["x"] });
t!("-- import: foo\nexport: x, y, z", { "import": "foo", "export": ["x", "y", "z"] });
t!("-- import: foo as f\nexport: x as y", { "import": "foo as f", "export": ["x=>y"] });
t!("-- import: foo as f\nexport: x as y, z", { "import": "foo as f", "export": ["x=>y", "z"] });
t!("-- import: foo as f\nexport: x\nexposing: y", { "import": "foo=>f", "export": ["x"], "exposing": ["y"] });
t!("-- import: foo\nexport: x\nexposing: y", { "import": "foo", "export": ["x"], "exposing": ["y"] });
t!("-- import: foo\nexport: x, y, z\nexposing: y", { "import": "foo", "export": ["x", "y", "z"], "exposing": ["y"] });
t!("-- import: foo as f\nexport: x as y\nexposing: y", { "import": "foo as f", "export": ["x=>y"], "exposing": ["y"] });
t!("-- import: foo as f\nexport: x as y, z\nexposing: y", { "import": "foo as f", "export": ["x=>y", "z"], "exposing": ["y"] });
}
}
12 changes: 12 additions & 0 deletions v0.5/fastn-unresolved/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,15 @@ pub(crate) fn assert_no_extra_headers(

!found
}

impl From<&str> for fastn_unresolved::Identifier {
fn from(s: &str) -> fastn_unresolved::Identifier {
fastn_unresolved::Identifier(s.to_string())
}
}

impl fastn_unresolved::Identifier {
pub fn from_str(s: &str) -> fastn_unresolved::Identifier {
fastn_unresolved::Identifier(s.to_string())
}
}

0 comments on commit 22ae86a

Please sign in to comment.