defmodule Systemd.UnitObject do
@moduledoc """
D-Bus object for a loaded systemd unit.
"""
alias Systemd.{Error, Properties, ServiceState, SocketState, TimerState, UnitState}
@interface "org.freedesktop.systemd1.Unit"
@enforce_keys [:object_path]
@type t :: %__MODULE__{name: String.t() | nil, object_path: String.t()}
defstruct [:name, :object_path]
@doc false
@spec new(String.t(), String.t() | nil) :: t()
def new(object_path, name \\ nil) when is_binary(object_path) do
%__MODULE__{name: name, object_path: object_path}
end
@doc """
Reads one property from the unit object.
"""
@spec property(pid(), t(), String.t()) :: {:ok, term()} | {:error, Error.t()}
def property(conn, %__MODULE__{object_path: path}, property) do
Properties.get(conn, path, @interface, property)
end
@doc """
Reads common unit state properties.
"""
@spec state(pid(), t()) :: {:ok, UnitState.t()} | {:error, Error.t()}
def state(conn, %__MODULE__{} = unit) do
typed_state(conn, unit, @interface, UnitState)
end
@doc """
Reads common service-specific properties.
"""
@spec service_state(pid(), t()) :: {:ok, ServiceState.t()} | {:error, Error.t()}
def service_state(conn, %__MODULE__{} = unit) do
typed_state(conn, unit, "org.freedesktop.systemd1.Service", ServiceState)
end
@doc """
Reads common socket-specific properties.
"""
@spec socket_state(pid(), t()) :: {:ok, SocketState.t()} | {:error, Error.t()}
def socket_state(conn, %__MODULE__{} = unit) do
typed_state(conn, unit, "org.freedesktop.systemd1.Socket", SocketState)
end
@doc """
Reads common timer-specific properties.
"""
@spec timer_state(pid(), t()) :: {:ok, TimerState.t()} | {:error, Error.t()}
def timer_state(conn, %__MODULE__{} = unit) do
typed_state(conn, unit, "org.freedesktop.systemd1.Timer", TimerState)
end
defp typed_state(conn, unit, interface, module) do
with {:ok, properties} <- Properties.get_all(conn, unit.object_path, interface) do
{:ok, module.from_properties(properties)}
end
end
end