github.com/misseven0/notify@v0.0.0-20230519123055-c1422e46da05/event.go (about)

     1  // Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be
     3  // found in the LICENSE file.
     4  
     5  package notify
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  )
    11  
    12  // Event represents the type of filesystem action.
    13  //
    14  // Number of available event values is dependent on the target system or the
    15  // watcher implmenetation used (e.g. it's possible to use either kqueue or
    16  // FSEvents on Darwin).
    17  //
    18  // Please consult documentation for your target platform to see list of all
    19  // available events.
    20  type Event uint32
    21  
    22  // Create, Remove, Write and Rename are the only event values guaranteed to be
    23  // present on all platforms.
    24  const (
    25  	Create = osSpecificCreate
    26  	Remove = osSpecificRemove
    27  	Write  = osSpecificWrite
    28  	Rename = osSpecificRename
    29  
    30  	// All is handful alias for all platform-independent event values.
    31  	All = Create | Remove | Write | Rename
    32  )
    33  
    34  const internal = recursive | omit
    35  
    36  // String implements fmt.Stringer interface.
    37  func (e Event) String() string {
    38  	var s []string
    39  	for _, strmap := range []map[Event]string{estr, osestr} {
    40  		for ev, str := range strmap {
    41  			if e&ev == ev {
    42  				s = append(s, str)
    43  			}
    44  		}
    45  	}
    46  	return strings.Join(s, "|")
    47  }
    48  
    49  // EventInfo describes an event reported by the underlying filesystem notification
    50  // subsystem.
    51  //
    52  // It always describes single event, even if the OS reported a coalesced action.
    53  // Reported path is absolute and clean.
    54  //
    55  // For non-recursive watchpoints its base is always equal to the path passed
    56  // to corresponding Watch call.
    57  //
    58  // The value of Sys if system-dependent and can be nil.
    59  //
    60  // # Sys
    61  //
    62  // Under Darwin (FSEvents) Sys() always returns a non-nil *notify.FSEvent value,
    63  // which is defined as:
    64  //
    65  //	type FSEvent struct {
    66  //	    Path  string // real path of the file or directory
    67  //	    ID    uint64 // ID of the event (FSEventStreamEventId)
    68  //	    Flags uint32 // joint FSEvents* flags (FSEventStreamEventFlags)
    69  //	}
    70  //
    71  // For possible values of Flags see Darwin godoc for notify or FSEvents
    72  // documentation for FSEventStreamEventFlags constants:
    73  //
    74  //	https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamEventFlags
    75  //
    76  // Under Linux (inotify) Sys() always returns a non-nil *unix.InotifyEvent
    77  // value, defined as:
    78  //
    79  //	type InotifyEvent struct {
    80  //	    Wd     int32    // Watch descriptor
    81  //	    Mask   uint32   // Mask describing event
    82  //	    Cookie uint32   // Unique cookie associating related events (for rename(2))
    83  //	    Len    uint32   // Size of name field
    84  //	    Name   [0]uint8 // Optional null-terminated name
    85  //	}
    86  //
    87  // More information about inotify masks and the usage of inotify_event structure
    88  // can be found at:
    89  //
    90  //	http://man7.org/linux/man-pages/man7/inotify.7.html
    91  //
    92  // Under Darwin, DragonFlyBSD, FreeBSD, NetBSD, OpenBSD (kqueue) Sys() always
    93  // returns a non-nil *notify.Kevent value, which is defined as:
    94  //
    95  //	type Kevent struct {
    96  //	    Kevent *syscall.Kevent_t // Kevent is a kqueue specific structure
    97  //	    FI     os.FileInfo       // FI describes file/dir
    98  //	}
    99  //
   100  // More information about syscall.Kevent_t can be found at:
   101  //
   102  //	https://www.freebsd.org/cgi/man.cgi?query=kqueue
   103  //
   104  // Under Windows (ReadDirectoryChangesW) Sys() always returns nil. The documentation
   105  // of watcher's WinAPI function can be found at:
   106  //
   107  //	https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx
   108  type EventInfo interface {
   109  	Event() Event     // event value for the filesystem action
   110  	Path() string     // real path of the file or directory
   111  	Sys() interface{} // underlying data source (can return nil)
   112  }
   113  
   114  type isDirer interface {
   115  	isDir() (bool, error)
   116  }
   117  
   118  var _ fmt.Stringer = (*event)(nil)
   119  var _ isDirer = (*event)(nil)
   120  
   121  // String implements fmt.Stringer interface.
   122  func (e *event) String() string {
   123  	return e.Event().String() + `: "` + e.Path() + `"`
   124  }
   125  
   126  var estr = map[Event]string{
   127  	Create: "notify.Create",
   128  	Remove: "notify.Remove",
   129  	Write:  "notify.Write",
   130  	Rename: "notify.Rename",
   131  	// Display name for recursive event is added only for debugging
   132  	// purposes. It's an internal event after all and won't be exposed to the
   133  	// user. Having Recursive event printable is helpful, e.g. for reading
   134  	// testing failure messages:
   135  	//
   136  	//    --- FAIL: TestWatchpoint (0.00 seconds)
   137  	//    watchpoint_test.go:64: want diff=[notify.Remove notify.Create|notify.Remove];
   138  	//    got [notify.Remove notify.Remove|notify.Create] (i=1)
   139  	//
   140  	// Yup, here the diff have Recursive event inside. Go figure.
   141  	recursive: "recursive",
   142  	omit:      "omit",
   143  }