| ... | ... | @@ -139,11 +139,12 @@ pub const Hash = struct { |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | 141 | pub fn projectId(hash: *const Hash) ProjectId { |
| 142 | | const name = std.mem.sliceTo(&hash.bytes, '-'); |
| 143 | | const hashplus = hash.bytes[std.mem.findScalarLast(u8, &hash.bytes, '-').? + 1 ..]; |
| 144 | | var decoded: [6]u8 = undefined; |
| 145 | | std.base64.url_safe_no_pad.Decoder.decode(&decoded, hashplus[0..8]) catch unreachable; |
| 146 | | const fingerprint_id = std.mem.readInt(u32, decoded[0..4], .little); |
| 142 | const bytes = hash.toSlice(); |
| 143 | const name = std.mem.sliceTo(bytes, '-'); |
| 144 | const encoded_hashplus = bytes[bytes.len - 44 ..]; |
| 145 | var hashplus: [33]u8 = undefined; |
| 146 | std.base64.url_safe_no_pad.Decoder.decode(&hashplus, encoded_hashplus) catch unreachable; |
| 147 | const fingerprint_id = std.mem.readInt(u32, hashplus[0..4], .little); |
| 147 | 148 | return .init(name, fingerprint_id); |
| 148 | 149 | } |
| 149 | 150 | |
| ... | ... | @@ -157,6 +158,17 @@ pub const Hash = struct { |
| 157 | 158 | |
| 158 | 159 | try std.testing.expectEqual(0xd8fa4f9a, project_id.fingerprint_id); |
| 159 | 160 | } |
| 161 | |
| 162 | test "projectId with dashes in the base64" { |
| 163 | const hash: Hash = .fromSlice("dvui-0.4.0-dev-AQFJmayi2gAKE7FeJoF61v5U1IV9-SupoEcFutIZYpkC"); |
| 164 | const project_id = hash.projectId(); |
| 165 | |
| 166 | var expected_name: [32]u8 = @splat(0); |
| 167 | expected_name[0.."dvui".len].* = "dvui".*; |
| 168 | try std.testing.expectEqualSlices(u8, &expected_name, &project_id.padded_name); |
| 169 | |
| 170 | try std.testing.expectEqual(0x99490101, project_id.fingerprint_id); |
| 171 | } |
| 160 | 172 | }; |
| 161 | 173 | |
| 162 | 174 | /// Minimum information required to identify whether a package is an artifact |