diff --git a/damus/Models/Post.swift b/damus/Models/Post.swift index 99da6fa7..40a4c2f3 100644 --- a/damus/Models/Post.swift +++ b/damus/Models/Post.swift @@ -70,14 +70,12 @@ func parse_post_bech32_mention(_ p: Parser) -> ReferencedId? { return nil } - var end = p.pos - if consume_until(p, match: { c in !is_bech32_char(c) }) { - end = p.pos - } else { - p.pos = start + guard consume_until(p, match: { c in !is_bech32_char(c) }, end_ok: true) else { return nil } + let end = p.pos + let sliced = String(substring(p.str, start: start, end: end)) guard let decoded = try? bech32_decode(sliced) else { p.pos = start diff --git a/damus/Util/Parser.swift b/damus/Util/Parser.swift index 682daaf0..5e77c63c 100644 --- a/damus/Util/Parser.swift +++ b/damus/Util/Parser.swift @@ -17,17 +17,22 @@ class Parser { } } -func consume_until(_ p: Parser, match: (Character) -> Bool) -> Bool { - var i: Int = 0 +func consume_until(_ p: Parser, match: (Character) -> Bool, end_ok: Bool = false) -> Bool { let sub = substring(p.str, start: p.pos, end: p.str.count) + let start = p.pos + for c in sub { if match(c) { - p.pos += i return true } - i += 1 + p.pos += 1 } + if end_ok { + return true + } + + p.pos = start return false } diff --git a/damusTests/ReplyTests.swift b/damusTests/ReplyTests.swift index 494395fe..0acd6c7d 100644 --- a/damusTests/ReplyTests.swift +++ b/damusTests/ReplyTests.swift @@ -189,6 +189,32 @@ class ReplyTests: XCTestCase { XCTAssertEqual(parsed.count, 0) } + func testBech32MentionAtStart() throws { + let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s" + let hex_pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + let content = "@\(pk) hello there" + let blocks = parse_post_blocks(content: content) + + XCTAssertEqual(blocks.count, 3) + XCTAssertEqual(blocks[0].is_text, "") + XCTAssertEqual(blocks[1].is_ref, ReferencedId(ref_id: hex_pk, relay_id: nil, key: "p")) + XCTAssertEqual(blocks[2].is_text, " hello there") + + } + + func testBech32MentionAtEnd() throws { + let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s" + let hex_pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" + let content = "this is a @\(pk)" + let blocks = parse_post_blocks(content: content) + + XCTAssertEqual(blocks.count, 3) + XCTAssertEqual(blocks[1].is_ref, ReferencedId(ref_id: hex_pk, relay_id: nil, key: "p")) + XCTAssertEqual(blocks[0].is_text, "this is a ") + XCTAssertEqual(blocks[2].is_text, "") + + } + func testNpubMention() throws { let evid = "0000000000000000000000000000000000000000000000000000000000000005" let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"