Skip to content

Conversation

@sawada-naoya
Copy link
Contributor

@sawada-naoya sawada-naoya commented Aug 24, 2025

This PR adds a Japanese (ja) translation map to the i18n package.

Changes:

  • Added i18n/ja/ja.go with a full translation map mirroring EN keys
  • Registered "ja" in the i18n registry (community maintained)
  • Added tests to ensure key parity with EN and spot-check representative messages
  • Updated docs to include "ja" in the Third Party Languages section and usage example

Notes:

  • Following the maintainer’s guidance, this is marked as a community-maintained translation
  • I commit to keeping parity with EN as new issue codes are added
  • If ja lags behind, fallback to EN remains safe

Thanks for reviewing!

Summary by CodeRabbit

  • New Features

    • Added Japanese localization for validation/error messages across all supported types, enabling apps to display messages in Japanese.
  • Documentation

    • Updated i18n guide to list Japanese as a supported third-party language and included examples for enabling and parsing errors in Japanese.
  • Tests

    • Added test coverage to verify Japanese translations and ensure correct message rendering.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 24, 2025

Walkthrough

Adds Japanese (ja) localization to i18n: documentation updated, comment examples adjusted, tests extended to cover ja, and a new ja Map introduced with comprehensive Japanese error messages across types.

Changes

Cohort / File(s) Summary
Docs: i18n package
docs/docs/packages/i18n.md
Adds Japanese to third-party languages, updates import and registration examples to include i18n/ja, and shows parsing with langKey = "ja".
i18n comments
i18n/i18n.go
Updates example comment to include ja: ja.Map in SetLanguagesErrsMap. No code changes.
Tests: add ja coverage
i18n/i18n_test.go
Introduces jaMap and includes ja in language registry; adds test asserting Japanese message ("必須です") for required string case.
New locale: Japanese
i18n/ja/ja.go
Adds package ja with exported Map (zconst.LangMap) providing Japanese messages for String/Bool/Number/Time/Slice/Struct issue codes, including negated variants and fallbacks.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant App as App/Validator
  participant I18N as i18n Registry
  participant JA as ja.Map

  Dev->>I18N: SetLanguagesErrsMap({"en": en.Map, "es": es.Map, "ja": ja.Map})
  Note right of I18N: Registers language maps

  App->>I18N: Resolve(lang="ja", type=String, code=Required)
  I18N->>JA: Lookup message for (String, Required)
  JA-->>I18N: "必須です"
  I18N-->>App: Localized message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Poem

In clovered code, I hop with glee,
A new “ja” whisper on the breeze—すてき!
Maps now chirp in kana’s light,
Tests bow, docs nod, all just right.
Thump-thump go my paws in rhyme,
Kon’nichiwa, i18n—multilingual time! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
i18n/i18n.go (1)

16-16: Comment example looks good; add JA inclusion. Also keep examples consistent with docs default.

The usage snippet correctly adds ja.Map. Minor nit: here the defaultLang in the example is "en", while the docs example uses "es" as default. Consider aligning both to reduce confusion.

docs/docs/packages/i18n.md (1)

48-50: Fix markdownlint MD010: replace hard tabs or disable for code fences.

markdownlint flagged hard tabs on these lines. Two options:

  • Preferred: replace leading tabs with spaces in code blocks.
  • Alternatively: disable MD010 for the specific code fence.

Apply this minimal change to replace tabs with spaces on the touched lines:

-import (
-	"github.com/Oudwins/zog/i18n" // import the i18n library
-	"github.com/Oudwins/zog/i18n/en"
-	"github.com/Oudwins/zog/i18n/es"
-	"github.com/Oudwins/zog/i18n/ja" // import any of the supported language maps or build your own
-)
+import (
+    "github.com/Oudwins/zog/i18n" // import the i18n library
+    "github.com/Oudwins/zog/i18n/en"
+    "github.com/Oudwins/zog/i18n/es"
+    "github.com/Oudwins/zog/i18n/ja" // import any of the supported language maps or build your own
+)
-	i18n.SetLanguagesErrsMap(map[string]i18n.LangMap{
-		"es": es.Map,
-		"en": en.Map,
-		"ja": ja.Map,
-	},
-		"es",                        // default language
-		i18n.WithLangKey("langKey"), // (optional) default lang key is "lang" and is stored in i18n.LangKey
-	)
+    i18n.SetLanguagesErrsMap(map[string]i18n.LangMap{
+        "es": es.Map,
+        "en": en.Map,
+        "ja": ja.Map,
+    },
+        "es",                        // default language
+        i18n.WithLangKey("langKey"), // (optional) default lang key is "lang" and is stored in i18n.LangKey
+    )

If you prefer disabling the rule for the fence instead, wrap it like:

<!-- markdownlint-disable MD010 -->
```go
... code ...



Also applies to: 53-55, 65-65

</blockquote></details>
<details>
<summary>i18n/ja/ja.go (2)</summary><blockquote>

`23-24`: **Consistency: unify wording for “NotNil/Empty”.**

Messages alternate between 「空であってはいけません」 and 「空ではいけません」. Consider picking one phrasing across types (e.g., 「空ではいけません」) or tailor per-type:  
- Strings/Slices: 「空であってはいけません」  
- Non-collection scalars (number/bool/time/struct): 「nil(未設定)ではいけません」

Purely stylistic; current text is understandable.



Also applies to: 43-44, 51-51, 64-64, 72-73, 83-83

---

`7-40`: **Excellent coverage and parity confirmed**

- A parity check between `i18n/en/en.go` and `i18n/ja/ja.go` shows no missing or extra `IssueCode` entries in the Japanese map.  
- All string validators—including `NotIssueCode` variants and placeholder keys—are covered in `ja.Map`.  
- Optional Japanese phrasing nitpick: for more natural negative forms, you might use 「〜であってはいけません」 instead of 「〜ではいけません」. For example:  
  • Current: 「有効なメールアドレスではいけません」  
  • Suggested: 「有効なメールアドレスであってはいけません」

</blockquote></details>
<details>
<summary>i18n/i18n_test.go (3)</summary><blockquote>

`22-26`: **Prefer using the real ja.Map instead of redefining jaMap here.**

Importing the new i18n/ja package keeps tests aligned with production translations and avoids drift.

Apply within this hunk:

```diff
-var jaMap = zconst.LangMap{
-	zconst.TypeString: {
-		zconst.IssueCodeRequired: "必須です",
-	},
-}

And add the import (outside this hunk; see below).


34-35: Wire the real ja.Map into SetLanguagesErrsMap.

With the import added, switch to:

-        "ja": jaMap,
+        "ja": ja.Map,

28-36: Optional: add a parity test to prevent key drift between EN and JA.

A lightweight test ensures JA keeps the same set of issue codes per type as EN. Example:

// add near other tests
func TestJALangMapParityWithEN(t *testing.T) {
    t.Parallel() // remove if global formatter causes flakiness
    enMap := en.Map
    jaMap := ja.Map

    // Compare keys per type
    for zogType, enIssues := range enMap {
        jaIssues, ok := jaMap[zogType]
        if !ok {
            t.Fatalf("ja.Map missing type %q", zogType)
        }
        // Build sets
        enSet := map[string]struct{}{}
        for code := range enIssues {
            enSet[string(code)] = struct{}{}
        }
        jaSet := map[string]struct{}{}
        for code := range jaIssues {
            jaSet[string(code)] = struct{}{}
        }

        for c := range enSet {
            if _, ok := jaSet[c]; !ok {
                t.Errorf("ja.Map missing issue code %q for type %q", c, zogType)
            }
        }
    }
}

Note: you’ll need to import:

  • "github.com/Oudwins/zog/i18n/en"
  • "github.com/Oudwins/zog/i18n/ja"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ac0ebac and 225131e.

📒 Files selected for processing (4)
  • docs/docs/packages/i18n.md (3 hunks)
  • i18n/i18n.go (1 hunks)
  • i18n/i18n_test.go (2 hunks)
  • i18n/ja/ja.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
i18n/ja/ja.go (3)
i18n/i18n.go (1)
  • LangMap (51-51)
zconst/consts.go (36)
  • ZogType (38-38)
  • ZogIssueCode (54-54)
  • TypeString (41-41)
  • IssueCodeLen (97-97)
  • IssueCodeEmail (123-123)
  • IssueCodeUUID (127-127)
  • IssueCodeMatch (131-131)
  • IssueCodeURL (135-135)
  • IssueCodeHasPrefix (139-139)
  • IssueCodeHasSuffix (143-143)
  • IssueCodeContains (101-101)
  • IssueCodeContainsDigit (155-155)
  • IssueCodeContainsUpper (147-147)
  • IssueCodeContainsLower (151-151)
  • IssueCodeContainsSpecial (159-159)
  • IssueCodeOneOf (85-85)
  • IssueCodeRequired (63-63)
  • IssueCodeNotNil (67-67)
  • IssueCodeMin (89-89)
  • IssueCodeMax (93-93)
  • IssueCodeFallback (77-77)
  • TypeBool (43-43)
  • IssueCodeEQ (81-81)
  • TypeNumber (42-42)
  • IssueCodeLTE (106-106)
  • IssueCodeLT (110-110)
  • IssueCodeGTE (114-114)
  • IssueCodeGT (118-118)
  • TypeTime (44-44)
  • IssueCodeAfter (164-164)
  • IssueCodeBefore (168-168)
  • TypeSlice (45-45)
  • TypeStruct (46-46)
  • IssueCodeInvalidJSON (182-182)
  • IssueCodeZHTTPInvalidForm (187-187)
  • IssueCodeZHTTPInvalidQuery (191-191)
zconst/utils.go (1)
  • NotIssueCode (7-12)
i18n/i18n_test.go (2)
i18n/i18n.go (2)
  • LangMap (51-51)
  • SetLanguagesErrsMap (19-38)
zconst/consts.go (3)
  • LangMap (36-36)
  • TypeString (41-41)
  • IssueCodeRequired (63-63)
🪛 markdownlint-cli2 (0.17.2)
docs/docs/packages/i18n.md

48-48: Hard tabs
Column: 1

(MD010, no-hard-tabs)


49-49: Hard tabs
Column: 1

(MD010, no-hard-tabs)


53-53: Hard tabs
Column: 1

(MD010, no-hard-tabs)


54-54: Hard tabs
Column: 1

(MD010, no-hard-tabs)


55-55: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (9)
docs/docs/packages/i18n.md (3)

17-17: Verify contributor attribution for Japanese.

Docs credit Japanese to @sarada824, while this PR is authored by @sawada-naoya. Please confirm intended attribution and update if necessary.


55-55: LGTM: JA registered in languages map.

Including "ja": ja.Map in the example correctly mirrors the implementation.


65-65: LGTM: JA usage example added.

The example showing z.WithCtxValue("langKey", "ja") clarifies how to select Japanese errors at parse time.

i18n/ja/ja.go (5)

50-61: LGTM: number translations and placeholders look correct.

lte/lt/gte/gt/eq and one-of variants are covered, including NotIssue for eq and one_of. Placeholders match expected keys.


62-69: LGTM: time translations.

after/before/eq handled with clear messages; reasonable fallback.


70-80: LGTM: slice translations, including NotIssue variants.

Min/Max/Len/Contains and negative forms present; good coverage.


81-91: LGTM: struct and JSON/ZHTTP issues.

Invalid JSON body, invalid form/query included and consistent with other locales.


41-48: Boolean issue codes confirmed
The constants IssueCodeTrue and IssueCodeFalse are already defined in zconst/consts.go (lines 173 and 177), so the Japanese translations can remain as-is.

i18n/i18n_test.go (1)

64-70: LGTM: JA test case.

Validates that “必須です” is returned under lang=ja for required errors. Reads well alongside EN/ES cases.

@Oudwins
Copy link
Owner

Oudwins commented Aug 24, 2025

Awesome!

@Oudwins Oudwins merged commit aa0ca94 into Oudwins:master Aug 24, 2025
5 checks passed
Oudwins pushed a commit that referenced this pull request Oct 3, 2025
* chore:add ja to the Third Party Languages list

* chore:add Japanese (ja) translation map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants