Skip to content

Commit

Permalink
Refactor (#1)
Browse files Browse the repository at this point in the history
Refactor the codebase for maintainability
  • Loading branch information
varnerac authored Oct 8, 2023
1 parent 641e0ea commit 8068d29
Show file tree
Hide file tree
Showing 49 changed files with 2,239 additions and 1,499 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: test
on:
push:
branches:
- master
- main
pull_request:

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.ez
build
erl_crash.dump
**/.DS_Store
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ gleam_stdlib = "~> 0.30"

[dev-dependencies]
gleeunit = "~> 0.10"
gleam_erlang = "~> 0.20"
simplifile = "~> 0.1.14"
4 changes: 2 additions & 2 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# You typically do not need to edit this file

packages = [
{ name = "gleam_erlang", version = "0.22.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "367D8B41A7A86809928ED1E7E55BFD0D46D7C4CF473440190F324AFA347109B4" },
{ name = "gleam_stdlib", version = "0.30.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "704258528887F95075FFED7AAE1CCF836A9B88E3AADA2F69F9DA15815F94A4F9" },
{ name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" },
{ name = "simplifile", version = "0.1.14", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "10EA0207796F20488A3A166C50A189C9385333F3C9FAC187729DE7B9CE4ADDBC" },
]

[requirements]
gleam_erlang = { version = "~> 0.20" }
gleam_stdlib = { version = "~> 0.30" }
gleeunit = { version = "~> 0.10" }
simplifile = { version = "~> 0.1.14" }
147 changes: 144 additions & 3 deletions src/glemur.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,146 @@
import gleam/io
import gleam/option.{Option}
import gleam/result
import gleam/list
import gleam/bit_string
import glemur/parse/util
import glemur/parse/doc
import glemur/parse/el
import glemur/parse/error
import glemur/parse/config.{Config}

pub fn main() {
io.println("Hello from glemur!")
pub type ElContent {
NoContent
Elements(List(Element))
CharData(String)
}

pub type ParseError {
InvalidName(String)
InvalidCharacter(String)
InvalidCharacterReference(String)
UnexpectedCharacter(String)
UnexpectedEndOfStream(String)
InvalidComment(String)
ForbiddenComment(String)
ForbiddenPi(String)
ForbiddenDtd(String)
InvalidAttributeNamespacePrefix(String)
InvalidElementNamespacePrefix(String)
InvalidElementPrefix(String)
InvalidNamespaceDecl(String)
InvalidNamespaceUri(String)
DuplicateAttributeNames(String)
}

pub type XmlVersion {
OneDotZero
}

pub type XmlDocument {
XmlDocument(
version: Option(XmlVersion),
encoding: Option(String),
standalone: Option(Bool),
pis: List(#(String, Option(String))),
el: Element,
)
}

pub type Element {
Element(
name: #(Option(String), String),
attrs: List(#(#(Option(String), String), String)),
pis: List(#(String, Option(String))),
content: ElContent,
)
}

pub fn parse_document(
config: Config,
str: String,
) -> Result(XmlDocument, ParseError) {
config
|> doc.parse_doc(bit_string.from_string(str))
|> result.map(fn(d) { convert_document(d) })
|> result.map_error(fn(e) { convert_error(e) })
}

fn convert_document(doc: doc.XmlDocument) -> XmlDocument {
let version = option.map(doc.version, fn(_) { OneDotZero })
XmlDocument(
version: version,
encoding: doc.encoding,
standalone: doc.standalone,
pis: doc.processing_instructions,
el: convert_element(doc.el),
)
}

pub fn parse_element(
config: Config,
str: String,
default_ns: Option(String),
ns_declarations: List(#(String, String)),
) -> Result(#(Element, String), ParseError) {
let el_rslt =
el.parse_el(
config,
bit_string.from_string(str),
default_ns,
ns_declarations,
)
|> result.map_error(convert_error)
|> result.map(fn(t) { #(t.0, convert_element(t.1)) })
use #(bs, el) <- result.try(el_rslt)
Ok(#(el, util.to_str(bs)))
}

fn convert_element(element: el.Element) -> Element {
case element {
el.Element(sub_els: [_, ..], ..) -> {
let new_sub_els = list.map(element.sub_els, convert_element)
Element(
name: element.name,
pis: element.pis,
attrs: element.attrs,
content: Elements(new_sub_els),
)
}
el.Element(cdata: "", sub_els: [], ..) ->
Element(
name: element.name,
pis: element.pis,
attrs: element.attrs,
content: NoContent,
)
_ ->
Element(
name: element.name,
pis: element.pis,
attrs: element.attrs,
content: CharData(element.cdata),
)
}
}

fn convert_error(err: error.ParserError) -> ParseError {
case err {
error.InvalidName(str) -> InvalidName(str)
error.InvalidCharacter(str) -> InvalidCharacter(str)
error.InvalidCharacterReference(str) -> InvalidCharacterReference(str)
error.UnexpectedCharacter(str) -> UnexpectedCharacter(str)
error.UnexpectedEndOfStream(str) -> UnexpectedEndOfStream(str)
error.InvalidComment(str) -> InvalidComment(str)
error.ForbiddenComment(str) -> ForbiddenComment(str)
error.ForbiddenPi(str) -> ForbiddenPi(str)
error.ForbiddenDtd(str) -> ForbiddenDtd(str)
error.InvalidAttributeNamespacePrefix(str) ->
InvalidAttributeNamespacePrefix(str)
error.InvalidElementNamespacePrefix(str) ->
InvalidElementNamespacePrefix(str)
error.InvalidElementPrefix(str) -> InvalidElementPrefix(str)
error.InvalidNamespaceDecl(str) -> InvalidNamespaceDecl(str)
error.InvalidNamespaceUri(str) -> InvalidNamespaceUri(str)
error.DuplicateAttributeNames(str) -> DuplicateAttributeNames(str)
}
}
Loading

0 comments on commit 8068d29

Please sign in to comment.