Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(castor): add DIDParser #17

Merged
merged 4 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Castor/Sources/Castor.swift

This file was deleted.

7 changes: 7 additions & 0 deletions Castor/Sources/CastorImpl+Public.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Domain

extension CastorImpl: Castor {
public func parseDID(str: String) throws -> DID {
try DIDParser(didString: str).parse()
}
}
1 change: 1 addition & 0 deletions Castor/Sources/CastorImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public struct CastorImpl {}
56 changes: 56 additions & 0 deletions Castor/Sources/DIDParser.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Antlr4
import Domain
import Foundation

struct DIDParser {
struct InvalidDIDStringError: Error {}

let didString: String

func parse() throws -> DID {
let inputStream = ANTLRInputStream(didString)
let lexer = DIDAbnfLexer(inputStream)
let tokenStream = CommonTokenStream(lexer)

let parser = try DIDAbnfParser(tokenStream)
parser.setErrorHandler(BailErrorStrategy())
let context = try parser.did()

let listener = Listener()
try ParseTreeWalker().walk(listener, context)

guard
let schema = listener.scheme,
let methodName = listener.methodName,
let methodId = listener.methodId
else { throw InvalidDIDStringError() }

let did = DID(
schema: schema,
method: methodName,
methodId: methodId
)

return did
}
}

fileprivate final class Listener: DIDAbnfBaseListener {
fileprivate var scheme: String?
fileprivate var methodName: String?
fileprivate var methodId: String?

override func exitDid(_ ctx: DIDAbnfParser.DidContext) {
ctx.SCHEMA().map { scheme = $0.getText() }
}

override func exitMethod_name(_ ctx: DIDAbnfParser.Method_nameContext) {
methodName = ctx.getText()
}

override func exitMethod_specific_id(
_ ctx: DIDAbnfParser.Method_specific_idContext
) {
methodId = ctx.getText()
}
}
41 changes: 41 additions & 0 deletions Castor/Tests/DIDParserTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import XCTest
@testable import Castor

final class DIDParserTests: XCTestCase {

func testValidDIDs() throws {
let didExample1 = "did:aaaaaa:aa:aaa"
let didExample2 = "did:prism01:b2.-_%11:b4._-%11"
let didExample3 = "did:prism:b6c0c33d701ac1b9a262a14454d1bbde3d127d697a76950963c5fd930605:Cj8KPRI7CgdtYXN0ZXIwEAFKLgoJc2VmsxEiECSTjyV7sUfCr_ArpN9rvCwR9fRMAhcsr_S7ZRiJk4p5k"

let parsedDID1 = try DIDParser(didString: didExample1).parse()
let parsedDID2 = try DIDParser(didString: didExample2).parse()
let parsedDID3 = try DIDParser(didString: didExample3).parse()

XCTAssertEqual(parsedDID1.schema, "did")
XCTAssertEqual(parsedDID1.method, "aaaaaa")
XCTAssertEqual(parsedDID1.methodId, "aa:aaa")

XCTAssertEqual(parsedDID2.schema, "did")
XCTAssertEqual(parsedDID2.method, "prism01")
XCTAssertEqual(parsedDID2.methodId, "b2.-_%11:b4._-%11")

XCTAssertEqual(parsedDID3.schema, "did")
XCTAssertEqual(parsedDID3.method, "prism")
XCTAssertEqual(parsedDID3.methodId, "b6c0c33d701ac1b9a262a14454d1bbde3d127d697a76950963c5fd930605:Cj8KPRI7CgdtYXN0ZXIwEAFKLgoJc2VmsxEiECSTjyV7sUfCr_ArpN9rvCwR9fRMAhcsr_S7ZRiJk4p5k")
}

func testInvalidDIDs() throws {
let didExample1 = "idi:aaaaaa:aa:aaa"
let didExample2 = "did:-prism-:aaaaa:aaaa"
let didExample3 = "did:prism:aaaaaaaaaaa::"
let didExample4 = "did::prism:aaaaaaaaaaa:aaaa"
let didExample5 = "did:prism::aaaaaaaaaaa:aaaa"

XCTAssertThrowsError(try DIDParser(didString: didExample1).parse())
XCTAssertThrowsError(try DIDParser(didString: didExample2).parse())
XCTAssertThrowsError(try DIDParser(didString: didExample3).parse())
XCTAssertThrowsError(try DIDParser(didString: didExample4).parse())
XCTAssertThrowsError(try DIDParser(didString: didExample5).parse())
}
}
3 changes: 3 additions & 0 deletions Domain/Sources/BBs/Castor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public protocol Castor {
func parseDID(str: String) throws -> DID
}