///|
/// Controls whether web content stays below or extends beneath the titlebar.
pub(all) enum TitlebarStyle {
  Default
  Overlay
} derive(Debug, Eq)

///|
pub extend TitlebarStyle with Eq::{not_equal, equal}

///|
pub extend TitlebarStyle with Debug::{to_repr}

///|
/// Describes the effective native window chrome theme.
pub(all) enum WindowTheme {
  Light
  Dark
} derive(Debug, Eq)

///|
pub extend WindowTheme with Eq::{not_equal, equal}

///|
pub extend WindowTheme with Debug::{to_repr}

///|
/// Controls how Proton chooses the native window chrome theme.
pub(all) enum WindowThemePreference {
  System
  Light
  Dark
} derive(Debug, Eq)

///|
pub extend WindowThemePreference with Eq::{not_equal, equal}

///|
pub extend WindowThemePreference with Debug::{to_repr}

///|
/// Explicit progress states for `WindowHandle::set_progress_bar`, mirroring
/// Electron's `mode` option. Only Windows renders the explicit states; macOS
/// and Linux derive the indicator from the progress value alone.
pub(all) enum ProgressBarMode {
  /// Derives the state from the value: a negative value clears the indicator,
  /// `0.0` through `1.0` is determinate, and values above `1.0` are
  /// indeterminate.
  Automatic
  Normal
  Indeterminate
  Error
  Paused
  /// Removes the indicator without changing the last reported value.
  Cleared
} derive(Debug, Eq)

///|
pub extend ProgressBarMode with Eq::{not_equal, equal}

///|
pub extend ProgressBarMode with Debug::{to_repr}

///|
fn ProgressBarMode::to_native(self : ProgressBarMode) -> @native.ProgressMode {
  match self {
    Automatic => @native.ProgressMode::Automatic
    Normal => @native.ProgressMode::Normal
    Indeterminate => @native.ProgressMode::Indeterminate
    Error => @native.ProgressMode::Error
    Paused => @native.ProgressMode::Paused
    Cleared => @native.ProgressMode::Cleared
  }
}

///|
/// Taskbar thumbnail-toolbar button flags, mirroring Electron's `flags` array.
/// A button is enabled unless `Disabled` or `NonInteractive` is present.
pub(all) enum ThumbarButtonFlag {
  Disabled
  DismissOnClick
  NoBackground
  Hidden
  NonInteractive
} derive(Debug, Eq)

///|
pub extend ThumbarButtonFlag with Eq::{not_equal, equal}

///|
pub extend ThumbarButtonFlag with Debug::{to_repr}

///|
fn ThumbarButtonFlag::to_native(
  self : ThumbarButtonFlag,
) -> @native.ThumbarButtonFlag {
  match self {
    Disabled => @native.ThumbarButtonFlag::Disabled
    DismissOnClick => @native.ThumbarButtonFlag::DismissOnClick
    NoBackground => @native.ThumbarButtonFlag::NoBackground
    Hidden => @native.ThumbarButtonFlag::Hidden
    NonInteractive => @native.ThumbarButtonFlag::NonInteractive
  }
}

///|
/// One button of the Windows taskbar thumbnail toolbar.
///
/// `id` identifies the button in `App::on_thumbar_button_click`, so rebuilding
/// the toolbar never changes what a click reports. `tooltip` is optional text
/// for the button, and `flags` controls its state.
pub(all) struct ThumbarButton {
  id : String
  icon : NativeImage
  tooltip : String
  flags : Array[ThumbarButtonFlag]
}

///|
fn ThumbarButton::to_native(self : ThumbarButton) -> @native.ThumbarButton {
  {
    id: self.id,
    icon: self.icon.image,
    tooltip: self.tooltip,
    flags: self.flags.map(flag => flag.to_native()),
  }
}

///|
/// One item inside a custom jump list category.
///
/// Empty strings mean "not set", which is how Electron treats omitted
/// properties: a task needs `path` and `title`, a file link needs `path`, and a
/// separator needs neither.
pub(all) struct JumpListItem {
  kind : JumpListItemKind
  path : String
  arguments : String
  title : String
  description : String
  icon_path : String
  icon_index : Int
  working_directory : String
}

///|
/// The kind of a jump list item, mirroring Electron's `type` property.
pub(all) enum JumpListItemKind {
  /// Launches `path` with `arguments`, shown as `title`.
  Task
  /// Separates items in the standard Tasks category; other categories reject
  /// it.
  Separator
  /// Opens `path` with the application that registered that file type.
  File
} derive(Debug, Eq)

///|
pub extend JumpListItemKind with Eq::{not_equal, equal}

///|
pub extend JumpListItemKind with Debug::{to_repr}

///|
fn JumpListItemKind::to_native(
  self : JumpListItemKind,
) -> @native.JumpListItemKind {
  match self {
    Task => @native.JumpListItemKind::Task
    Separator => @native.JumpListItemKind::Separator
    File => @native.JumpListItemKind::File
  }
}

///|
/// One category of the custom jump list, mirroring Electron's
/// `JumpListCategory`.
pub(all) struct JumpListCategory {
  kind : JumpListCategoryKind
  /// Required when `kind` is `Custom`, ignored otherwise.
  name : String
  /// Used by `Tasks` and `Custom`; `Recent` and `Frequent` are managed by
  /// Windows.
  items : Array[JumpListItem]
}

///|
/// The kind of a jump list category, mirroring Electron's `type` property.
pub(all) enum JumpListCategoryKind {
  /// The standard Tasks category, always shown at the bottom.
  Tasks
  /// An application-named category holding tasks and file links.
  Custom
  /// The Windows-managed recent files category.
  Recent
  /// The Windows-managed frequently used category.
  Frequent
} derive(Debug, Eq)

///|
pub extend JumpListCategoryKind with Eq::{not_equal, equal}

///|
pub extend JumpListCategoryKind with Debug::{to_repr}

///|
fn JumpListCategoryKind::to_native(
  self : JumpListCategoryKind,
) -> @native.JumpListCategoryKind {
  match self {
    Tasks => @native.JumpListCategoryKind::Tasks
    Custom => @native.JumpListCategoryKind::Custom
    Recent => @native.JumpListCategoryKind::Recent
    Frequent => @native.JumpListCategoryKind::Frequent
  }
}

///|
fn JumpListCategory::to_native(
  self : JumpListCategory,
) -> @native.JumpListCategory {
  {
    kind: self.kind.to_native(),
    name: self.name,
    items: self.items.map(item => item.to_native()),
  }
}

///|
fn JumpListItem::to_native(self : JumpListItem) -> @native.JumpListItem {
  {
    kind: self.kind.to_native(),
    path: self.path,
    arguments: self.arguments,
    title: self.title,
    description: self.description,
    icon_path: self.icon_path,
    icon_index: self.icon_index,
    working_directory: self.working_directory,
  }
}

///|
/// The result of a jump list update, mirroring the strings Electron returns
/// from `setJumpList`.
pub(all) enum JumpListResult {
  /// Nothing went wrong.
  Ok
  /// One or more categories or items failed.
  Error
  /// A separator was added to a category other than Tasks.
  InvalidSeparator
  /// A file link was added for a file type the application does not handle.
  FileTypeRegistrationError
  /// Windows denied custom categories through privacy or group policy.
  CustomCategoryAccessDenied
  /// The platform has no jump list. Proton reports this instead of Electron's
  /// undefined method on macOS and Linux.
  Unsupported
} derive(Debug, Eq)

///|
pub extend JumpListResult with Eq::{not_equal, equal}

///|
pub extend JumpListResult with Debug::{to_repr}

///|
fn JumpListResult::from_native(
  result : @native.JumpListResult,
) -> JumpListResult {
  match result {
    @native.JumpListResult::Ok => Ok
    @native.JumpListResult::Error => Error
    @native.JumpListResult::InvalidSeparator => InvalidSeparator
    @native.JumpListResult::FileTypeRegistrationError =>
      FileTypeRegistrationError
    @native.JumpListResult::CustomCategoryAccessDenied =>
      CustomCategoryAccessDenied
    @native.JumpListResult::Unsupported => Unsupported
  }
}

///|
/// Replaces the application's custom Windows jump list, or removes it when
/// `categories` is `None`.
///
/// Mirrors Electron's `app.setJumpList`. The result reports what Windows did:
/// `Ok`, `Error`, `InvalidSeparator` when a separator appears outside the Tasks
/// category, `FileTypeRegistrationError` when a file link has no registered
/// handler, and `CustomCategoryAccessDenied` when privacy or group policy
/// settings block custom categories. macOS and Linux report `Unsupported`,
/// where Electron leaves the method undefined.
///
/// The list belongs to the application's AppUserModelID. An installed
/// application registers that identity in its installer; without one Windows
/// derives it from the executable path, which is the same identity the taskbar
/// button uses. Users can remove items from custom categories, and Windows
/// ignores any category that re-adds a removed item until the next successful
/// call.
pub fn set_jump_list(
  categories : Array[JumpListCategory]?,
) -> JumpListResult raise AppControlError {
  let native_categories = match categories {
    Some(groups) => Some(groups.map(category => category.to_native()))
    None => None
  }
  JumpListResult::from_native(@native.jump_list_apply(native_categories)) catch {
    error => raise app_control_native_error("set jump list", error)
  }
}

///|
/// Controls how configured window dimensions constrain native resizing.
pub(all) enum WindowSizeHint {
  Unconstrained
  Fixed
  Min
  Max
} derive(Debug, Eq)

///|
pub extend WindowSizeHint with Eq::{not_equal, equal}

///|
pub extend WindowSizeHint with Debug::{to_repr}

///|
/// Geometry and scaling information for the monitor containing a window.
pub(all) struct WindowMonitor {
  x : Int
  y : Int
  width : Int
  height : Int
  work_x : Int
  work_y : Int
  work_width : Int
  work_height : Int
  scale_factor_percent : Int
} derive(Debug, Eq)

///|
pub extend WindowMonitor with Eq::{not_equal, equal}

///|
pub extend WindowMonitor with Debug::{to_repr}

///|
fn WindowMonitor::from_native(monitor : @native.WindowMonitor) -> WindowMonitor {
  {
    x: monitor.x,
    y: monitor.y,
    width: monitor.width,
    height: monitor.height,
    work_x: monitor.work_x,
    work_y: monitor.work_y,
    work_width: monitor.work_width,
    work_height: monitor.work_height,
    scale_factor_percent: monitor.scale_factor_percent,
  }
}

///|
/// A point-in-time snapshot of a native window.
///
/// `theme` is the effective `Light` or `Dark` theme after resolving the
/// window's configured `WindowThemePreference`.
pub(all) struct WindowState {
  x : Int
  y : Int
  width : Int
  height : Int
  monitor : WindowMonitor
  zoom_percent : Int
  visible : Bool
  focused : Bool
  minimized : Bool
  maximized : Bool
  fullscreen : Bool
  always_on_top : Bool
  theme : WindowTheme
} derive(Debug, Eq)

///|
pub extend WindowState with Eq::{not_equal, equal}

///|
pub extend WindowState with Debug::{to_repr}

///|
fn WindowState::from_native(state : @native.WindowState) -> WindowState {
  {
    x: state.x,
    y: state.y,
    width: state.width,
    height: state.height,
    monitor: WindowMonitor::from_native(state.monitor),
    zoom_percent: state.zoom_percent,
    visible: state.visible,
    focused: state.focused,
    minimized: state.minimized,
    maximized: state.maximized,
    fullscreen: state.fullscreen,
    always_on_top: state.always_on_top,
    theme: match state.theme {
      @native.WindowTheme::Light => WindowTheme::Light
      @native.WindowTheme::Dark => WindowTheme::Dark
    },
  }
}

///|
/// A point-in-time snapshot of a window's main browser page.
pub(all) struct BrowserState {
  url : String
  title : String
  is_loading : Bool
  can_go_back : Bool
  can_go_forward : Bool
} derive(Debug, Eq)

///|
pub extend BrowserState with Eq::{not_equal, equal}

///|
pub extend BrowserState with Debug::{to_repr}

///|
fn BrowserState::from_native(state : @native.BrowserState) -> BrowserState {
  {
    url: state.url,
    title: state.title,
    is_loading: state.is_loading,
    can_go_back: state.can_go_back,
    can_go_forward: state.can_go_forward,
  }
}

///|
fn FindInPageResult::from_native(
  result : @native.NativeFindInPageResult,
) -> FindInPageResult {
  {
    request_id: result.request_id,
    active_match_ordinal: result.active_match_ordinal,
    matches: result.matches,
    selection_x: result.selection_x,
    selection_y: result.selection_y,
    selection_width: result.selection_width,
    selection_height: result.selection_height,
    final_update: result.final_update,
  }
}

///|
/// Information about one connected display.
pub(all) struct ScreenInfo {
  id : Int
  x : Int
  y : Int
  width : Int
  height : Int
  work_x : Int
  work_y : Int
  work_width : Int
  work_height : Int
  scale_factor_percent : Int
  is_primary : Bool
} derive(Debug, Eq)

///|
pub extend ScreenInfo with Eq::{not_equal, equal}

///|
pub extend ScreenInfo with Debug::{to_repr}

///|
fn ScreenInfo::from_native(screen : @native.ScreenInfo) -> ScreenInfo {
  {
    id: screen.id,
    x: screen.x,
    y: screen.y,
    width: screen.width,
    height: screen.height,
    work_x: screen.work_x,
    work_y: screen.work_y,
    work_width: screen.work_width,
    work_height: screen.work_height,
    scale_factor_percent: screen.scale_factor_percent,
    is_primary: screen.is_primary,
  }
}

///|
/// Failures while querying connected displays.
pub(all) suberror ScreenQueryError {
  QueryFailed(status~ : Int, detail~ : String)
} derive(Debug)

///|
pub extend ScreenQueryError with Debug::{to_repr}

///|
/// Returns information about the displays currently visible to the app.
pub fn screens() -> Array[ScreenInfo] raise ScreenQueryError {
  let native_screens = @native.screens() catch {
    error => raise QueryFailed(status=error.status(), detail=error.message())
  }
  native_screens.map(ScreenInfo::from_native)
}

///|
/// A point-in-time web contents view state snapshot.
pub(all) struct ViewState {
  x : Int
  y : Int
  width : Int
  height : Int
  visible : Bool
  z_order : Int
} derive(Debug, Eq)

///|
pub extend ViewState with Eq::{not_equal, equal}

///|
pub extend ViewState with Debug::{to_repr}

///|
fn ViewState::from_native(state : @native.ViewState) -> ViewState {
  {
    x: state.x,
    y: state.y,
    width: state.width,
    height: state.height,
    visible: state.visible,
    z_order: state.z_order,
  }
}

///|
/// Describes the operating system appearance reported by the native theme
/// query.
pub(all) struct NativeTheme {
  dark_colors : Bool
  high_contrast_colors : Bool
  source : WindowThemePreference
}

///|
/// Raised when the operating system appearance cannot be read.
pub(all) suberror NativeThemeError {
  NativeThemeUnavailable(status~ : Int, detail~ : String)
}

///|
pub fn NativeTheme::should_use_dark_colors(self : NativeTheme) -> Bool {
  self.dark_colors
}

///|
pub fn NativeTheme::should_use_high_contrast_colors(self : NativeTheme) -> Bool {
  self.high_contrast_colors
}

///|
/// Reports the application theme source that drives the snapshot, matching
/// Electron's `nativeTheme.themeSource`.
pub fn NativeTheme::theme_source(self : NativeTheme) -> WindowThemePreference {
  self.source
}

///|
fn NativeTheme::from_native(
  snapshot : @native.NativeThemeSnapshot,
) -> NativeTheme {
  {
    dark_colors: snapshot.dark_colors,
    high_contrast_colors: snapshot.high_contrast_colors,
    source: match snapshot.source {
      @native.WindowThemePreference::System => WindowThemePreference::System
      @native.WindowThemePreference::Light => WindowThemePreference::Light
      @native.WindowThemePreference::Dark => WindowThemePreference::Dark
    },
  }
}

///|
fn native_theme_source_code(source : WindowThemePreference) -> Int {
  match source {
    WindowThemePreference::System => 0
    WindowThemePreference::Light => 1
    WindowThemePreference::Dark => 2
  }
}

///|
fn native_theme_source_from_code(code : Int) -> WindowThemePreference {
  match code {
    1 => WindowThemePreference::Light
    2 => WindowThemePreference::Dark
    _ => WindowThemePreference::System
  }
}

///|
/// Overrides the application-level theme source, matching Electron's
/// `nativeTheme.themeSource`.
///
/// `Light` and `Dark` win over the operating system value reported by
/// `native_theme()`; `System` restores the operating system value. Per-window
/// `WindowHandle::set_window_theme` stays authoritative for that window's
/// chrome.
pub fn native_theme_set_source(
  source : WindowThemePreference,
) -> Unit raise NativeThemeError {
  @native.native_theme_set_source(native_theme_source_code(source)) catch {
    error =>
      raise NativeThemeUnavailable(
        status=error.status(),
        detail=error.message(),
      )
  }
}

///|
/// Reports the operating system appearance Proton follows.
///
/// Mirrors Electron's `nativeTheme` query surface: it is window independent
/// and does not require a running session. Renderer `prefers-color-scheme`
/// keeps following the operating system, because the current CEF public API
/// exposes no renderer color-scheme override.
pub fn native_theme() -> NativeTheme raise NativeThemeError {
  let (dark_colors, high_contrast_colors, source) = @native.native_theme_query() catch {
    error =>
      raise NativeThemeUnavailable(
        status=error.status(),
        detail=error.message(),
      )
  }
  {
    dark_colors,
    high_contrast_colors,
    source: native_theme_source_from_code(source),
  }
}

///|
/// Configuration for a web contents view hosted inside a window.
pub struct ViewConfig {
  x : Int
  y : Int
  width : Int
  height : Int
  visible : Bool
  z_order : Int
  initial_url : String
  background_color : String?
}

///|
pub fn ViewConfig::ViewConfig(
  width~ : Int,
  height~ : Int,
  x? : Int = 0,
  y? : Int = 0,
  visible? : Bool = true,
  z_order? : Int = 0,
  initial_url? : String = "about:blank",
  background_color? : String,
) -> ViewConfig {
  { x, y, width, height, visible, z_order, initial_url, background_color, }
}

///|
fn ViewConfig::to_native(self : ViewConfig) -> @native.ViewConfig {
  @native.ViewConfig(
    width=self.width,
    height=self.height,
    x=self.x,
    y=self.y,
    visible=self.visible,
    z_order=self.z_order,
    initial_url=self.initial_url,
    background_color?=self.background_color,
  )
}

///|
let menu_item_command : Int = 0

///|
let menu_item_separator : Int = 1

///|
let menu_item_role : Int = 2

///|
let menu_item_submenu : Int = 3

///|
/// A standard top-level application menu role.
pub(all) enum MenuRole {
  Application
  File
  Edit
  View
  Window
  Help
} derive(Debug, Eq)

///|
pub extend MenuRole with Eq::{not_equal, equal}

///|
pub extend MenuRole with Debug::{to_repr}

///|
fn MenuRole::to_native(self : MenuRole) -> @native.MenuRole {
  match self {
    Application => @native.MenuRole::Application
    File => @native.MenuRole::File
    Edit => @native.MenuRole::Edit
    View => @native.MenuRole::View
    Window => @native.MenuRole::Window
    Help => @native.MenuRole::Help
  }
}

///|
/// A standard native menu action.
pub(all) enum MenuItemRole {
  Quit
  Hide
  HideOthers
  ShowAll
  Close
  Minimize
  Zoom
  Undo
  Redo
  Cut
  Copy
  Paste
  SelectAll
} derive(Debug, Eq)

///|
pub extend MenuItemRole with Eq::{not_equal, equal}

///|
pub extend MenuItemRole with Debug::{to_repr}

///|
fn MenuItemRole::to_native(self : MenuItemRole) -> @native.MenuItemRole {
  match self {
    Quit => @native.MenuItemRole::Quit
    Hide => @native.MenuItemRole::Hide
    HideOthers => @native.MenuItemRole::HideOthers
    ShowAll => @native.MenuItemRole::ShowAll
    Close => @native.MenuItemRole::Close
    Minimize => @native.MenuItemRole::Minimize
    Zoom => @native.MenuItemRole::Zoom
    Undo => @native.MenuItemRole::Undo
    Redo => @native.MenuItemRole::Redo
    Cut => @native.MenuItemRole::Cut
    Copy => @native.MenuItemRole::Copy
    Paste => @native.MenuItemRole::Paste
    SelectAll => @native.MenuItemRole::SelectAll
  }
}

///|
/// A command, separator, or platform role in a native application menu.
pub struct MenuItem {
  kind : Int
  id : String?
  label : String?
  key : String?
  role : MenuItemRole?
  submenu : Menu?
  enabled : Bool
  visible : Bool
  checked : Bool?
}

///|
/// Creates a command item. `enabled` and `visible` control native
/// presentation. Passing `checked` creates a checkbox command item; omitting it
/// creates a normal command item.
pub fn MenuItem::command(
  id : String,
  label : String,
  key? : String,
  enabled? : Bool = true,
  visible? : Bool = true,
  checked? : Bool,
) -> MenuItem {
  {
    kind: menu_item_command,
    id: Some(id),
    label: Some(label),
    key,
    role: None,
    submenu: None,
    enabled,
    visible,
    checked,
  }
}

///|
pub fn MenuItem::separator() -> MenuItem {
  {
    kind: menu_item_separator,
    id: None,
    label: None,
    key: None,
    role: None,
    submenu: None,
    enabled: true,
    visible: true,
    checked: None,
  }
}

///|
pub fn MenuItem::role(
  role : MenuItemRole,
  label? : String,
  key? : String,
) -> MenuItem {
  {
    kind: menu_item_role,
    id: None,
    label,
    key,
    role: Some(role),
    submenu: None,
    enabled: true,
    visible: true,
    checked: None,
  }
}

///|
/// Creates a nested submenu item with its own set of items.
pub fn MenuItem::submenu(label : String, items~ : Array[MenuItem]) -> MenuItem {
  {
    kind: menu_item_submenu,
    id: None,
    label: None,
    key: None,
    role: None,
    submenu: Some({ label: Some(label), role: None, items: Some(items.copy()), }),
    enabled: true,
    visible: true,
    checked: None,
  }
}

///|
fn MenuItem::to_native(self : MenuItem) -> @native.MenuItem {
  match self.kind {
    0 =>
      @native.MenuItem::command(
        self.id.unwrap_or(""),
        self.label.unwrap_or(""),
        key?=self.key,
        enabled=self.enabled,
        visible=self.visible,
        checked?=self.checked,
      )
    1 => @native.MenuItem::separator()
    3 => {
      let sub = self.submenu.unwrap()
      @native.MenuItem::submenu(
        sub.label.unwrap_or(""),
        items=sub.items.unwrap_or([]).map(item => item.to_native()),
      )
    }
    _ =>
      @native.MenuItem::role(
        self.role.unwrap().to_native(),
        label?=self.label,
        key?=self.key,
      )
  }
}

///|
/// A top-level native menu and its items.
pub struct Menu {
  label : String?
  role : MenuRole?
  items : Array[MenuItem]?
}

///|
pub fn Menu::Menu(label : String, items~ : Array[MenuItem]) -> Menu {
  { label: Some(label), role: None, items: Some(items.copy()), }
}

///|
/// Creates a standard top-level menu. Omitted items select the role defaults;
/// an explicit item array replaces those defaults exactly.
pub fn Menu::role(
  role : MenuRole,
  label? : String,
  items? : Array[MenuItem],
) -> Menu {
  { label, role: Some(role), items: items.map(items => items.copy()), }
}

///|
fn Menu::to_native(self : Menu) -> @native.Menu {
  match self.role {
    Some(role) =>
      @native.Menu::role(
        role.to_native(),
        label?=self.label,
        items?=self.items.map(items => items.map(item => item.to_native())),
      )
    None =>
      @native.Menu(
        self.label.unwrap_or(""),
        items=self.items.unwrap_or([]).map(item => item.to_native()),
      )
  }
}

///|
/// An application-level native menu bar.
pub struct MenuBar {
  menus : Array[Menu]
}

///|
pub fn MenuBar::MenuBar(menus~ : Array[Menu]) -> MenuBar {
  { menus, }
}

///|
fn MenuBar::to_native(self : MenuBar) -> @native.MenuBar {
  @native.MenuBar(menus=self.menus.map(menu => menu.to_native()))
}

///|
/// Structured information about a bridge bootstrap or runtime failure.
pub(all) struct BridgeDiagnostic {
  stage : String
  code : String
  message : String
  page_instance : String
  url : String
  owner : String?
  source_url : String?
  source_line : String?
  line : Int?
  column : Int?
  stack : String?
  additional_failure_count : Int?
  details_truncated : Bool
} derive(Debug, Eq)

///|
pub extend BridgeDiagnostic with Eq::{not_equal, equal}

///|
pub extend BridgeDiagnostic with Debug::{to_repr}

///|
fn BridgeDiagnostic::from_native(
  diagnostic : @native.BridgeDiagnostic,
) -> BridgeDiagnostic {
  {
    stage: diagnostic.stage,
    code: diagnostic.code,
    message: diagnostic.message,
    page_instance: diagnostic.page_instance,
    url: diagnostic.url,
    owner: diagnostic.owner,
    source_url: diagnostic.source_url,
    source_line: diagnostic.source_line,
    line: diagnostic.line,
    column: diagnostic.column,
    stack: diagnostic.stack,
    additional_failure_count: diagnostic.additional_failure_count,
    details_truncated: diagnostic.details_truncated,
  }
}