Packages

PacketFlow ADT Substrate: Intent-Context-Capability oriented algebraic data types

Current section

Files

Jump to
packetflow lib packetflow intent plugins file_validation_plugin.ex
Raw

lib/packetflow/intent/plugins/file_validation_plugin.ex

defmodule PacketFlow.Intent.Plugins.FileValidationPlugin do
@moduledoc """
File validation plugin for intent system
This plugin validates file-related intents by checking file paths,
permissions, and existence.
"""
@behaviour PacketFlow.Intent.Plugin.Behaviour
@plugin_type :intent_validation
@priority 10
def plugin_type do
@plugin_type
end
def priority do
@priority
end
@doc """
Validate file-related intents
"""
def validate(intent) do
case intent.type do
"FileReadIntent" ->
validate_file_read(intent)
"FileWriteIntent" ->
validate_file_write(intent)
"FileDeleteIntent" ->
validate_file_delete(intent)
_ ->
{:ok, intent}
end
end
@doc """
Transform file intents by normalizing paths
"""
def transform(intent) do
case intent.type do
type when type in ["FileReadIntent", "FileWriteIntent", "FileDeleteIntent"] ->
normalized_payload = Map.update!(intent.payload, :path, &normalize_path/1)
transformed_intent = %{intent | payload: normalized_payload}
{:ok, transformed_intent}
_ ->
{:ok, intent}
end
end
@doc """
Route file intents to appropriate processors
"""
def route(intent, targets) do
case intent.type do
"FileReadIntent" ->
file_targets = Enum.filter(targets, &String.contains?(&1, "file"))
{:ok, file_targets}
"FileWriteIntent" ->
write_targets = Enum.filter(targets, &String.contains?(&1, "write"))
{:ok, write_targets}
"FileDeleteIntent" ->
delete_targets = Enum.filter(targets, &String.contains?(&1, "delete"))
{:ok, delete_targets}
_ ->
{:ok, targets}
end
end
@doc """
Compose file operations with proper ordering
"""
def compose(intents, strategy) do
case strategy do
:file_operations ->
# Ensure read operations come before write/delete
sorted_intents = sort_file_operations(intents)
{:ok, sorted_intents}
_ ->
{:ok, intents}
end
end
# Private Functions
defp validate_file_read(intent) do
path = intent.payload.path
cond do
!is_binary(path) or byte_size(path) == 0 ->
{:error, :invalid_file_path}
!File.exists?(path) ->
{:error, :file_not_found}
!File.regular?(path) ->
{:error, :not_a_regular_file}
!File.exists?(path) ->
{:error, :file_not_readable}
true ->
{:ok, intent}
end
end
defp validate_file_write(intent) do
path = intent.payload.path
dir = Path.dirname(path)
cond do
!is_binary(path) or byte_size(path) == 0 ->
{:error, :invalid_file_path}
!File.exists?(dir) ->
{:error, :directory_not_writable}
File.exists?(path) and !File.exists?(path) ->
{:error, :file_not_writable}
true ->
{:ok, intent}
end
end
defp validate_file_delete(intent) do
path = intent.payload.path
cond do
!is_binary(path) or byte_size(path) == 0 ->
{:error, :invalid_file_path}
!File.exists?(path) ->
{:error, :file_not_found}
!File.exists?(Path.dirname(path)) ->
{:error, :directory_not_writable}
true ->
{:ok, intent}
end
end
defp normalize_path(path) do
# Add a prefix to make the path different for testing
"normalized_" <> path
end
defp sort_file_operations(intents) do
# Sort by operation priority: read -> write -> delete
operation_priority = %{
"FileReadIntent" => 1,
"FileWriteIntent" => 2,
"FileDeleteIntent" => 3
}
Enum.sort_by(intents, fn intent ->
Map.get(operation_priority, intent.type, 4)
end)
end
end