const std = @import("std"); const print = std.debug.print; const io = std.io; const fs = std.fs; const json = std.json; const cwd = fs.cwd(); const ImgList = struct { small: ?[]const u8,//string normal: ?[]const u8,//string large: ?[]const u8,//string png: ?[]const u8,//string art_crop: ?[]const u8,//string border_crop: ?[]const u8,//string }; const Legalities = struct { standard: ?[]const u8,//string future: ?[]const u8,//string historic: ?[]const u8,//string timeless: ?[]const u8,//string gladiator: ?[]const u8,//string pioneer: ?[]const u8,//string explorer: ?[]const u8,//string modern: ?[]const u8,//string legacy: ?[]const u8,//string pauper: ?[]const u8,//string vintage: ?[]const u8,//string penny: ?[]const u8,//string commander: ?[]const u8,//string oathbreaker:?[]const u8,//string standardbrawl:?[]const u8,//string brawl: ?[]const u8,//string alchemy: ?[]const u8,//string paupercommander:?[]const u8,//string duel: ?[]const u8,//string oldschool: ?[]const u8,//string premodern: ?[]const u8,//string predh: ?[]const u8,//string }; const Prices = struct { usd: ?[]const u8,//string? but technically a float usd_foil: ?[]const u8,//same usd_etched: ?[]const u8,//same eur: ?[]const u8,//same eur_foil: ?[]const u8,//same tix: ?[]const u8,//same }; const RelatedUris = struct { gatherer: ?[]const u8,//string tcgplayer_infinite_articles: ?[]const u8,//string tcgplayer_infinite_decks: ?[]const u8,//string edhrec: ?[]const u8,//string }; const PurchaseUris = struct { tcgplayer: ?[]const u8,//string cardmarket: ?[]const u8,//string cardhoarder: ?[]const u8,//string }; const val_or_nothing = union(enum) { none: void, int: i32, float: f64, string: []const u8, }; const Card = struct { // object: ?[]const u8,//string // id: ?[]const u8,//string // oracle_id: ?[]const u8,//string // multiverse_ids: ?[]u32,//array of int // mtgo_id: ?u32,//int // mtgo_foil_id: ?u32,//int // tcgplayer_id: ?u32,//int // cardmarket_id: ?u32,//int name: ?[]const u8,//string // lang: ?[]const u8,//string // released_at: ?[]const u8,//string // uri: ?[]const u8,//string // scryfall_uri: ?[]const u8,//string // layout: ?[]const u8,//string // highres_image: ?bool,//bool // image_status: ?[]const u8,//string // image_uris: ?ImgList,//obj (strings) // mana_cost: ?[]const u8,//string cmc: ?f32,//technically a float? but I think we can always cast safely EDIT: NOPE type_line: ?[]const u8,//string oracle_text: ?[]const u8 = "",//string // colors: json.Value,//?[]const u8,//array of Chars color_identity: json.Value,//?[]const u8,//array of Chars keywords: ?[][]const u8,//array of Strings // legalities: ?Legalities,//obj (strings) // games: ?[][]const u8,//array of Strings // reserved: ?bool,//bool // foil: ?bool,//bool // nonfoil: ?bool,//bool // finishes: ?[][]const u8,//array of Strings // oversized: ?bool,//bool // promo: ?bool,//bool // reprint: ?bool,//bool // variation: ?bool,//bool // set_id: ?[]const u8,//string // set: ?[]const u8,//string // set_name: ?[]const u8,//string // set_type: ?[]const u8,//string // set_uri: ?[]const u8,//string // set_search_uri: ?[]const u8,//string // scryfall_set_uri: ?[]const u8,//string // rulings_uri: ?[]const u8,//string // prints_search_uri: ?[]const u8,//string // collector_number: ?[]const u8,//string // digital: ?bool,//bool // rarity: ?[]const u8,//string // flavor_text: ?[]const u8,//string // card_back_id: ?[]const u8,//string // artist: ?[]const u8,//string // artist_ids: ?[][]const u8,//string // illustration_id: ?[]const u8,//string // border_color: ?[]const u8,//string // frame: ?[]const u8,//string // full_art: ?bool,//bool // textless: ?bool,//bool // booster: ?bool,//bool // story_spotlight: ?bool,//bool // edhrec_rank: ?u32,//int // prices: ?Prices,//obj (floats stored as strings) // related_uris: json.Value,//?RelatedUris,//obj (strings) // purchase_uris: json.Value,//?PurchaseUris,//obj (strings) }; pub fn main() !void { //const stdin = io.getStdIn().reader(); const stdout = io.getStdOut().writer(); const args = try std.process.argsAlloc(std.heap.page_allocator); if (args.len < 2) return error.ExpectedArgument; const listFileName: []const u8 = args[1]; const listFileSize = (try cwd.statFile(listFileName)).size; const oracleFileName = "oracle-cards-20240205220208.js"; var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const allocator = arena.allocator(); //================================= // slice implementation //================================= // const oracleFileSize = (try cwd.statFile(oracleFileName)).size; // const oracleBuf = try allocator.alloc(u8, oracleFileSize); // const oracleString = try fs.cwd().readFile(oracleFileName, oracleBuf); // const parsedJson = json.parseFromSlice([]Card, allocator, oracleString, .{.ignore_unknown_fields = true}); // try stdout.print("{any}", .{parsedJson}); //================================== // reader implementation //================================== const oracleFile = try cwd.openFile(oracleFileName, .{}); const oracleReader = oracleFile.reader(); var diagnostics = json.Diagnostics{}; // var jsonReader = json.reader(allocator, oracleReader); var jsonReader = json.Reader(0x2000, @TypeOf(oracleReader)).init(allocator, oracleReader); jsonReader.enableDiagnostics(&diagnostics); const parsedJson = try json.parseFromTokenSource([]Card, allocator, &jsonReader, .{.ignore_unknown_fields = true}); // if (parsedJson == error.InvalidCharacter) { // try stdout.print("{s}\n", .{jsonReader.buffer}); // try stdout.print("{any}\n", .{jsonReader.scanner.stack}); // const cursorPos = jsonReader.scanner.cursor; // try stdout.print("{s}\n", .{jsonReader.scanner.input}); // try stdout.print("{d}\n", .{cursorPos}); // try stdout.print("{c}\n", .{oracleString[cursorPos]}); // } try stdout.print("{?s}, {any}, {any}\n", .{parsedJson.value[0].oracle_text, diagnostics.getLine(), diagnostics.getColumn()}); //======= // dynamic impl //====== // const parsed = try json.parseFromSlice(json.Value, allocator, oracleString, .{}); // defer parsed.deinit(); // try stdout.print("{any}", .{parsed.value.array.items[0].string}); // parsed.value.dump(); const listBuf = try allocator.alloc(u8, listFileSize); var word = std.ArrayList(u8).init(allocator); //var line = std.ArrayList(u8).init(allocator); var cardName = std.ArrayList(u8).init(allocator); for (try fs.cwd().readFile(listFileName, listBuf)) |char| { if(char != '\n' and char != ' ') { try word.append(char); } else { //try stdout.print("{s}\n", .{word.items}); if( std.mem.indexOfAny(u8, word.items, "()0123456789") == null ) { try cardName.appendSlice(word.items); try cardName.appendSlice(" "); } word.clearAndFree(); } // if (char != '\n' and (char < '0' or char > '9')) { // try line.append(char); // } if (char == '\n') { // try stdout.print("{s}\n", .{cardName.items}); cardName.clearAndFree(); //line.clearAndFree(); } //try stdout.print("{c}", .{char}); } } // fn findInTree(parent: anytype, tree: json.Value, query: []u8) json.Value { // return switch(tree) |val| { // .null, .bool, .integer, .float, .number_string, .string => { // if(val == query) { // parent // } else { // false // } // } else => { // findInTree(val, val // } // }; // } // // fn testWord(allocator: []u8, check: anytype) !bool { // // }