go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/pkg/funcs/read_file.go (about)

     1  /*
     2  
     3  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package funcs
     9  
    10  import (
    11  	"bufio"
    12  	"context"
    13  	"fmt"
    14  	"io"
    15  	"os"
    16  	"time"
    17  
    18  	"go.charczuk.com/projects/nodes/pkg/incrutil"
    19  )
    20  
    21  func ReadFile[Output any](ctx context.Context, filepath string, modTime time.Time) (output Output, err error) {
    22  	err = ReadFileAny(ctx, filepath, &output)
    23  	return
    24  }
    25  
    26  func ReadFileAny(_ context.Context, filepath string, output any) error {
    27  	f, err := os.Open(os.ExpandEnv(filepath))
    28  	if err != nil {
    29  		return err
    30  	}
    31  	defer f.Close()
    32  
    33  	if typed, ok := output.(*string); ok {
    34  		contents, err := io.ReadAll(f)
    35  		if err != nil {
    36  			return err
    37  		}
    38  		*typed = string(contents)
    39  		return nil
    40  	}
    41  
    42  	scan := bufio.NewScanner(f)
    43  	for scan.Scan() {
    44  		line := scan.Text()
    45  
    46  		switch outputTyped := output.(type) {
    47  		case *[]bool:
    48  			lineValue, err := incrutil.CastValue[bool](line)
    49  			if err != nil {
    50  				return err
    51  			}
    52  			*outputTyped = append(*outputTyped, lineValue)
    53  		case *[]int64:
    54  			lineValue, err := incrutil.CastValue[int64](line)
    55  			if err != nil {
    56  				return err
    57  			}
    58  			*outputTyped = append(*outputTyped, lineValue)
    59  		case *[]string:
    60  			*outputTyped = append(*outputTyped, line)
    61  		case *[]float64:
    62  			lineValue, err := incrutil.CastValue[float64](line)
    63  			if err != nil {
    64  				return err
    65  			}
    66  			*outputTyped = append(*outputTyped, lineValue)
    67  		case *[]time.Time:
    68  			lineValue, err := incrutil.CastValue[time.Time](line)
    69  			if err != nil {
    70  				return err
    71  			}
    72  			*outputTyped = append(*outputTyped, lineValue)
    73  		case *[]time.Duration:
    74  			lineValue, err := incrutil.CastValue[time.Duration](line)
    75  			if err != nil {
    76  				return err
    77  			}
    78  			*outputTyped = append(*outputTyped, lineValue)
    79  		default:
    80  			return fmt.Errorf("invalid readFile output type: %T", output)
    81  		}
    82  	}
    83  	return nil
    84  }