diff options
| author | Ruben Beltran del Rio <jj@r.bdr.sh> | 2025-12-14 16:16:22 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <jj@r.bdr.sh> | 2025-12-14 16:40:52 +0100 |
| commit | 0b90075f76b6f2df77c01c303322323b1395641a (patch) | |
| tree | 4e13d3ce0b1f4792eab8d04caefda2218565f5a9 /Sources/WmapParser/WmapParser.swift | |
| parent | 088a941a72c2f3e9b3382eb9c5d2f21203dd401c (diff) | |
Use WmapParser namespace
Diffstat (limited to 'Sources/WmapParser/WmapParser.swift')
| -rw-r--r-- | Sources/WmapParser/WmapParser.swift | 129 |
1 files changed, 63 insertions, 66 deletions
diff --git a/Sources/WmapParser/WmapParser.swift b/Sources/WmapParser/WmapParser.swift index f2bef8f..41843b3 100644 --- a/Sources/WmapParser/WmapParser.swift +++ b/Sources/WmapParser/WmapParser.swift @@ -1,79 +1,76 @@ import Foundation -// Public API ////////////////////////////////////////////////////////////////// +public struct WmapParser { -/// Parses a wmap source string. -public func parse(_ source: String) -> Map { - source.utf8.withContiguousStorageIfAvailable { bytes in - parseBytes(bytes) - } ?? parseBytes(Array(source.utf8)) -} - -// Parsers ///////////////////////////////////////////////////////////////////// + // Public API ////////////////////////////////////////////////////////////////// -struct LineParserContext { - var components: [Component] - var dependencies: [Dependency] - var keywordContext: KeywordParserContext -} + /// Parses a wmap source string. + public static func parse(_ source: String) -> Map { + source.utf8.withContiguousStorageIfAvailable { bytes in + parseBytes(bytes) + } ?? parseBytes(Array(source.utf8)) + } -/// Main parsing function, we work on bytes as it's faster. -private func parseBytes<T: Collection>(_ bytes: T) -> Map where T.Element == UInt8, T.Index == Int { - let estimatedLines = bytes.count / 30 + // Parsers ///////////////////////////////////////////////////////////////////// - var context = LineParserContext( - components: [], - dependencies: [], - keywordContext: KeywordParserContext( - stages: [], - notes: [], - groups: [], - inertias: [], - evolutions: [] - ) - ) + /// Main parsing function, we work on bytes as it's faster. + private static func parseBytes<T: Collection>(_ bytes: T) -> Map where T.Element == UInt8, T.Index == Int { + let estimatedLines = bytes.count / 30 - context.components.reserveCapacity(estimatedLines) - context.dependencies.reserveCapacity(estimatedLines) - context.keywordContext.notes.reserveCapacity(estimatedLines / 10) - context.keywordContext.stages.reserveCapacity(4) - context.keywordContext.groups.reserveCapacity(estimatedLines / 20) - context.keywordContext.inertias.reserveCapacity(estimatedLines / 20) - context.keywordContext.evolutions.reserveCapacity(estimatedLines / 20) + var context = LineParserContext( + components: [], + dependencies: [], + keywordContext: KeywordParserContext( + stages: [], + notes: [], + groups: [], + inertias: [], + evolutions: [] + ) + ) - var index = 0 - let length = bytes.count + context.components.reserveCapacity(estimatedLines) + context.dependencies.reserveCapacity(estimatedLines) + context.keywordContext.notes.reserveCapacity(estimatedLines / 10) + context.keywordContext.stages.reserveCapacity(4) + context.keywordContext.groups.reserveCapacity(estimatedLines / 20) + context.keywordContext.inertias.reserveCapacity(estimatedLines / 20) + context.keywordContext.evolutions.reserveCapacity(estimatedLines / 20) - while index < length { - guard let (start, end) = extractLine(bytes, &index, length) else { continue } - parseLine(bytes, start, end, &context) - } + var index = 0 + let length = bytes.count - return Map( - components: context.components, - dependencies: context.dependencies, - notes: context.keywordContext.notes, - stages: context.keywordContext.stages, - groups: context.keywordContext.groups, - inertias: context.keywordContext.inertias, - evolutions: context.keywordContext.evolutions - ) -} + while index < length { + guard let (start, end) = extractLine(bytes, &index, length) else { continue } + parseLine(bytes, start, end, &context) + } -/// Given a trimmed line, checks if it's a keyword, dependency or component -/// and parses it. -@inline(__always) -private func parseLine<T: Collection>( - _ bytes: T, _ start: Int, _ end: Int, - _ context: inout LineParserContext -) where T.Element == UInt8, T.Index == Int { - if bytes[start] == kOpenSquareBracket { - parseKeywordLine(bytes, start, end, &context.keywordContext) - } else if let separatorIndex = hasDependency(bytes, start, end) { - if let dependency = parseDependency(bytes, start, end, separatorIndex) { - context.dependencies.append(dependency) + return Map( + components: context.components, + dependencies: context.dependencies, + notes: context.keywordContext.notes, + stages: context.keywordContext.stages, + groups: context.keywordContext.groups, + inertias: context.keywordContext.inertias, + evolutions: context.keywordContext.evolutions + ) } - } else if let component = parseComponent(bytes, start, end) { - context.components.append(component) - } + + /// Given a trimmed line, checks if it's a keyword, dependency or component + /// and parses it. + @inline(__always) + private static func parseLine<T: Collection>( + _ bytes: T, _ start: Int, _ end: Int, + _ context: inout LineParserContext + ) where T.Element == UInt8, T.Index == Int { + if bytes[start] == kOpenSquareBracket { + parseKeywordLine(bytes, start, end, &context.keywordContext) + } else if let separatorIndex = hasDependency(bytes, start, end) { + if let dependency = parseDependency(bytes, start, end, separatorIndex) { + context.dependencies.append(dependency) + } + } else if let component = parseComponent(bytes, start, end) { + context.components.append(component) + } + } } |