From 1b90ce41e6f0f397a93e07a8a3242a3137e4abf3 Mon Sep 17 00:00:00 2001 From: despiegk Date: Thu, 21 Aug 2025 11:15:08 +0200 Subject: [PATCH] ... --- examples/data/countries.vsh | 44 ++++++++++++++++++++++ lib/data/countries/factory.v | 72 ++++++++++++++++++++++++++++++++++++ lib/data/countries/model.v | 29 +++++++++++++++ 3 files changed, 145 insertions(+) create mode 100755 examples/data/countries.vsh create mode 100644 lib/data/countries/factory.v create mode 100644 lib/data/countries/model.v diff --git a/examples/data/countries.vsh b/examples/data/countries.vsh new file mode 100755 index 00000000..7fda2020 --- /dev/null +++ b/examples/data/countries.vsh @@ -0,0 +1,44 @@ +#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run + +import freeflowuniverse.herolib.data.countries + +mut all_countries := countries.get_all_countries() or { + eprintln('Error loading countries: ${err}') + return +} + +println('Total countries loaded: ${all_countries.len}') + +// --- Example: Print the first few countries --- +println('\n--- First 5 Countries ---') +for i, country in all_countries { + if i >= 5 { break } + println(country.str()) +} + +// --- Example: Find a specific country (e.g., Belgium) --- +println('\n--- Searching for Belgium ---') +found := false +for country in all_countries { + if country.iso == 'BE' { + println('Found Belgium: ${country.str()}') + found = true + break + } +} +if !found { + println('Belgium not found.') +} + +// --- Example: Find countries in Europe (Continent = EU) --- +println('\n--- Countries in Europe (EU) ---') +mut eu_countries := []countries.Country{} +for country in all_countries { + if country.continent == 'EU' { + eu_countries << country + } +} +println('Found ${eu_countries.len} European countries.') +// Optionally print them or process further + + diff --git a/lib/data/countries/factory.v b/lib/data/countries/factory.v new file mode 100644 index 00000000..9355dc02 --- /dev/null +++ b/lib/data/countries/factory.v @@ -0,0 +1,72 @@ +module countries + +import os +import strings + +// --- Embed the data file content at compile time --- +// The path is relative to the location of this `module.v` file. +const embedded_country_data = $embed_file('data/countryInfo.txt') + +// get_all_countries parses the country data embedded in the executable. +// It returns a list of Country structs. +pub fn get_all_countries() ![]Country { + mut countries_list := []Country{} + + // --- Parse the embedded string --- + lines := embedded_country_data.split_into_lines() + mut found_header := false + + for line in lines { + // --- Skip empty lines and comments --- + if line == '' || line.trim_space().starts_with('#') { + continue + } + + // --- Identify and skip the header --- + // Check if this line looks like the header (contains key identifiers) + if !found_header && line.contains('ISO') && line.contains('Country') && line.contains('CurrencyCode') { + found_header = true + continue // Skip the header line itself + } + + // --- Process data lines --- + // Split the line by tab character + fields := line.split('\t') + + // Ensure we have the expected number of fields (header indicates 19) + if fields.len < 19 { + // Handle potential parsing errors or incomplete lines + // println('Warning: Skipping line with insufficient fields (found ${fields.len}): "${line}"') + continue + } + + // --- Create Country struct instance --- + // Map fields by index based on the header structure + country := Country{ + iso: fields[0].trim_space() + iso3: fields[1].trim_space() + iso_numeric: fields[2].trim_space() + fips: fields[3].trim_space() + country_name: fields[4].trim_space() + capital: fields[5].trim_space() + area_sqkm: fields[6].trim_space() + population: fields[7].trim_space() + continent: fields[8].trim_space() + tld: fields[9].trim_space() + currency_code: fields[10].trim_space() + currency_name: fields[11].trim_space() + phone: fields[12].trim_space() + postal_format: fields[13].trim_space() + postal_regex: fields[14].trim_space() + languages: fields[15].trim_space() + geonameid: fields[16].trim_space() + neighbours: fields[17].trim_space() + equiv_fips_code: fields[18].trim_space() // Handle potential trailing empty fields or newlines + } + + // --- Append to list --- + countries_list << country + } + + return countries_list +} diff --git a/lib/data/countries/model.v b/lib/data/countries/model.v new file mode 100644 index 00000000..7a5b9f66 --- /dev/null +++ b/lib/data/countries/model.v @@ -0,0 +1,29 @@ +module countries + +// Country represents a country entry from countryInfo.txt +pub struct Country { + iso string // ISO + iso3 string // ISO3 + iso_numeric string // ISO-Numeric + fips string // fips + country_name string // Country + capital string // Capital + area_sqkm string // Area(in sq km) (Keeping as string for potential parsing issues, convert later if needed) + population string // Population (Keeping as string for potential parsing issues, convert later if needed) + continent string // Continent + tld string // tld + currency_code string // CurrencyCode + currency_name string // CurrencyName + phone string // Phone + postal_format string // Postal Code Format + postal_regex string // Postal Code Regex + languages string // Languages + geonameid string // geonameid (Keeping as string for potential parsing issues, convert later if needed) + neighbours string // neighbours + equiv_fips_code string // EquivalentFipsCode +} + +// Optional: Add a method for better printing/debugging +pub fn (c Country) str() string { + return 'Country{iso: "${c.iso}", country_name: "${c.country_name}", continent: "${c.continent}", currency_code: "${c.currency_code}"}' +}